mirror of
https://github.com/microtherion/VocalEasel.git
synced 2024-12-22 19:23:59 +00:00
Use MIDI Sequences
This commit is contained in:
parent
fe55af3f7c
commit
a80c82cb18
|
@ -15,17 +15,6 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
const int kMidiChannelInUse = 0;
|
|
||||||
|
|
||||||
enum {
|
|
||||||
kMidiMessage_ControlChange = 0xB,
|
|
||||||
kMidiMessage_ProgramChange = 0xC,
|
|
||||||
kMidiMessage_BankMSBControl = 0,
|
|
||||||
kMidiMessage_BankLSBControl = 32,
|
|
||||||
kMidiMessage_NoteOn = 0x9,
|
|
||||||
kMidiMessage_NoteOff = 0x8
|
|
||||||
};
|
|
||||||
|
|
||||||
class VLAUSoundOut : public VLSoundOut {
|
class VLAUSoundOut : public VLSoundOut {
|
||||||
public:
|
public:
|
||||||
VLAUSoundOut();
|
VLAUSoundOut();
|
||||||
|
@ -34,49 +23,22 @@ public:
|
||||||
virtual void PlayChord(const VLChord & chord);
|
virtual void PlayChord(const VLChord & chord);
|
||||||
|
|
||||||
virtual ~VLAUSoundOut();
|
virtual ~VLAUSoundOut();
|
||||||
|
|
||||||
|
void Stop();
|
||||||
private:
|
private:
|
||||||
AUGraph fGraph;
|
AUGraph fGraph;
|
||||||
AudioUnit fSynth;
|
MusicPlayer fPlayer;
|
||||||
|
MusicSequence fMusic;
|
||||||
bool fRunning;
|
bool fRunning;
|
||||||
|
|
||||||
void Run();
|
void PlaySequence(MusicSequence music);
|
||||||
void Stop();
|
|
||||||
void Play(const int8_t * note, size_t numNotes = 1);
|
void Play(const int8_t * note, size_t numNotes = 1);
|
||||||
protected:
|
|
||||||
friend class VLAUSoundEvent;
|
|
||||||
|
|
||||||
void Play(const int8_t * note, size_t numNotes,
|
|
||||||
UInt32 msg, UInt32 velocity);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
VLSoundEvent::~VLSoundEvent()
|
VLSoundEvent::~VLSoundEvent()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
class VLAUSoundEvent : public VLSoundEvent {
|
|
||||||
public:
|
|
||||||
VLAUSoundEvent(VLAUSoundOut * soundOut,
|
|
||||||
const int8_t * note, size_t numNotes,
|
|
||||||
UInt32 msg, UInt32 velocity)
|
|
||||||
: fSoundOut(soundOut), fNotes(note, note+numNotes),
|
|
||||||
fMsg(msg), fVelocity(velocity)
|
|
||||||
{}
|
|
||||||
|
|
||||||
virtual void Perform();
|
|
||||||
private:
|
|
||||||
VLAUSoundOut * fSoundOut;
|
|
||||||
std::vector<int8_t> fNotes;
|
|
||||||
UInt32 fMsg;
|
|
||||||
UInt32 fVelocity;
|
|
||||||
};
|
|
||||||
|
|
||||||
void VLAUSoundEvent::Perform()
|
|
||||||
{
|
|
||||||
fSoundOut->Play(&fNotes[0], fNotes.size(), fMsg, fVelocity);
|
|
||||||
|
|
||||||
delete this;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VLSoundScheduler::Schedule(VLSoundEvent * what, float when)
|
void VLSoundScheduler::Schedule(VLSoundEvent * what, float when)
|
||||||
{
|
{
|
||||||
usleep((int)(1000000.0f*when));
|
usleep((int)(1000000.0f*when));
|
||||||
|
@ -93,6 +55,12 @@ VLSoundOut * VLSoundOut::Instance()
|
||||||
if (!sSoundScheduler.get())
|
if (!sSoundScheduler.get())
|
||||||
sSoundScheduler.reset(new VLSoundScheduler);
|
sSoundScheduler.reset(new VLSoundScheduler);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VLSoundOut * VLSoundOut::Instance()
|
||||||
|
{
|
||||||
|
if (!sSoundOut.get())
|
||||||
|
sSoundOut.reset(new VLAUSoundOut);
|
||||||
|
|
||||||
return sSoundOut.get();
|
return sSoundOut.get();
|
||||||
}
|
}
|
||||||
|
@ -107,7 +75,7 @@ VLSoundOut::~VLSoundOut()
|
||||||
}
|
}
|
||||||
|
|
||||||
VLAUSoundOut::VLAUSoundOut()
|
VLAUSoundOut::VLAUSoundOut()
|
||||||
: fRunning(false)
|
: fRunning(false), fMusic(0)
|
||||||
{
|
{
|
||||||
AUNode synthNode, limiterNode, outNode;
|
AUNode synthNode, limiterNode, outNode;
|
||||||
ComponentDescription cd;
|
ComponentDescription cd;
|
||||||
|
@ -136,39 +104,42 @@ VLAUSoundOut::VLAUSoundOut()
|
||||||
AUGraphOpen(fGraph);
|
AUGraphOpen(fGraph);
|
||||||
AUGraphConnectNodeInput(fGraph, synthNode, 0, limiterNode, 0);
|
AUGraphConnectNodeInput(fGraph, synthNode, 0, limiterNode, 0);
|
||||||
AUGraphConnectNodeInput(fGraph, limiterNode, 0, outNode, 0);
|
AUGraphConnectNodeInput(fGraph, limiterNode, 0, outNode, 0);
|
||||||
AUGraphGetNodeInfo(fGraph, synthNode, 0, 0, 0, &fSynth);
|
|
||||||
|
|
||||||
AUGraphInitialize(fGraph);
|
AUGraphInitialize(fGraph);
|
||||||
|
|
||||||
MusicDeviceMIDIEvent(fSynth,
|
NewMusicPlayer(&fPlayer);
|
||||||
kMidiMessage_ControlChange << 4 | kMidiChannelInUse,
|
|
||||||
kMidiMessage_BankMSBControl, 0,
|
|
||||||
0/*sample offset*/);
|
|
||||||
MusicDeviceMIDIEvent(fSynth,
|
|
||||||
kMidiMessage_ProgramChange << 4 | kMidiChannelInUse,
|
|
||||||
0/*prog change num*/, 0,
|
|
||||||
0/*sample offset*/);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VLAUSoundOut::~VLAUSoundOut()
|
VLAUSoundOut::~VLAUSoundOut()
|
||||||
{
|
{
|
||||||
|
DisposeMusicPlayer(fPlayer);
|
||||||
Stop();
|
Stop();
|
||||||
DisposeAUGraph(fGraph);
|
DisposeAUGraph(fGraph);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VLAUSoundOut::Run()
|
void VLAUSoundOut::PlaySequence(MusicSequence music)
|
||||||
{
|
{
|
||||||
if (!fRunning) {
|
Stop();
|
||||||
AUGraphStart(fGraph);
|
|
||||||
|
fMusic = music;
|
||||||
|
|
||||||
|
MusicSequenceSetAUGraph(fMusic, fGraph);
|
||||||
|
MusicPlayerSetSequence(fPlayer, fMusic);
|
||||||
|
MusicPlayerStart(fPlayer);
|
||||||
|
|
||||||
fRunning = true;
|
fRunning = true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void VLAUSoundOut::Stop()
|
void VLAUSoundOut::Stop()
|
||||||
{
|
{
|
||||||
|
MusicPlayerStop(fPlayer);
|
||||||
if (fRunning) {
|
if (fRunning) {
|
||||||
AUGraphStop(fGraph);
|
|
||||||
fRunning = false;
|
fRunning = false;
|
||||||
|
if (fMusic) {
|
||||||
|
MusicPlayerSetSequence(fPlayer, NULL);
|
||||||
|
DisposeMusicSequence(fMusic);
|
||||||
|
fMusic = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,20 +162,17 @@ void VLAUSoundOut::PlayChord(const VLChord & chord)
|
||||||
|
|
||||||
void VLAUSoundOut::Play(const int8_t * note, size_t numNotes)
|
void VLAUSoundOut::Play(const int8_t * note, size_t numNotes)
|
||||||
{
|
{
|
||||||
Run();
|
MusicSequence music;
|
||||||
|
MusicTrack track;
|
||||||
|
|
||||||
const UInt32 kNoteOn = kMidiMessage_NoteOn << 4 | kMidiChannelInUse;
|
NewMusicSequence(&music);
|
||||||
const UInt32 kNoteOff = kMidiMessage_NoteOff << 4 | kMidiChannelInUse;
|
MusicSequenceNewTrack(music, &track);
|
||||||
const UInt32 kNoteVelocity= 127;
|
|
||||||
|
|
||||||
Play(note, numNotes, kNoteOn, kNoteVelocity);
|
const int8_t kNoteVelocity = 127;
|
||||||
sSoundScheduler.get()->Schedule(
|
for (int i=0; i<numNotes; ++i) {
|
||||||
new VLAUSoundEvent(this, note, numNotes, kNoteOff, kNoteVelocity), 0.5f);
|
MIDINoteMessage n = {0, note[i], kNoteVelocity, 0, 1.0};
|
||||||
|
MusicTrackNewMIDINoteEvent(track, 0.0, &n);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VLAUSoundOut::Play(const int8_t * note, size_t numNotes,
|
PlaySequence(music);
|
||||||
UInt32 msg, UInt32 velocity)
|
|
||||||
{
|
|
||||||
for (size_t i = 0; i<numNotes; ++i)
|
|
||||||
MusicDeviceMIDIEvent(fSynth, msg, note[i], velocity, 0);
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user