diff --git a/JuceLibraryCode/AppConfig.h b/JuceLibraryCode/AppConfig.h index d446736..57c1428 100644 --- a/JuceLibraryCode/AppConfig.h +++ b/JuceLibraryCode/AppConfig.h @@ -227,7 +227,7 @@ #define JucePlugin_WantsMidiInput 1 #endif #ifndef JucePlugin_ProducesMidiOutput - #define JucePlugin_ProducesMidiOutput 0 + #define JucePlugin_ProducesMidiOutput 1 #endif #ifndef JucePlugin_SilenceInProducesSilenceOut #define JucePlugin_SilenceInProducesSilenceOut 0 diff --git a/Source/JaySynth.cpp b/Source/JaySynth.cpp index 4dc03db..8f21bae 100644 --- a/Source/JaySynth.cpp +++ b/Source/JaySynth.cpp @@ -108,11 +108,21 @@ JaySynth::JaySynth (int num_voices, String pathToWaves) m_num_audiothreads = SystemStats::getNumCpus(); m_ppAudioThread = new JaySynthThread*[m_num_audiothreads]; - m_pEventAudioThreadRdy = new WaitableEvent[m_num_audiothreads]; + m_ppEventAudioThreadRdy = new WaitableEvent*[m_num_audiothreads]; + SynthDebug("Creating threads...\n"); for (i=0; i < m_num_audiothreads; i++) - m_ppAudioThread[i] = new JaySynthThread(&m_pEventAudioThreadRdy[i], m_pVoices, num_voices, i, m_num_audiothreads); - + { + m_ppEventAudioThreadRdy[i] = new WaitableEvent(); + m_ppAudioThread[i] = new JaySynthThread(m_ppEventAudioThreadRdy[i], m_pVoices, num_voices, i, m_num_audiothreads); + } + + SynthDebug("Starting %d threads ...\n", m_num_audiothreads); + for (i=0; i < m_num_audiothreads; i++) + { + m_ppAudioThread[i]->startThread (12); + } + m_clockdiv = 0; m_lastTime_ms = 0; m_lastTimeError_ms = 0; @@ -124,9 +134,23 @@ JaySynth::~JaySynth() { int i, j; + SynthDebug("Stopping threads...\n"); + for (i=0; i < m_num_audiothreads; i++) + { + m_ppAudioThread[i]->stopThread(10000); + } + SynthDebug("Deleting threads...\n"); + for (i=0; i < m_num_audiothreads; i++) + { + delete(m_ppAudioThread[i]); + } + delete(m_ppAudioThread); + + SynthDebug("delete params\n"); paramInfoFree(&pb_range[0]); paramInfoFree(&pb_range[1]); + SynthDebug("delete voices\n"); for (i=0; i < SYNTH_NUM_PARAMS; i++) { for (j=0; j < max_num_voices; j++) @@ -140,17 +164,18 @@ JaySynth::~JaySynth() delete (ppHumanizedSliders); for (i = max_num_voices; --i >= 0;) + { removeVoice(i); + } delete (pPer_voice_controls); delete (pCurrNoteInfos); delete (m_pVoices); - for (i=0; i < m_num_audiothreads; i++) - delete(m_ppAudioThread[i]); - - delete(m_ppAudioThread); - delete(m_pEventAudioThreadRdy); + { + delete (m_ppEventAudioThreadRdy[i]); + } + delete(m_ppEventAudioThreadRdy); } @@ -970,7 +995,7 @@ void JaySynth::renderNextBlock (AudioSampleBuffer& outputBuffer, // Wait for audio threads finishing and add buffer for (i=0; i < m_num_audiothreads; i++) { - m_pEventAudioThreadRdy[i].wait(-1); + m_ppEventAudioThreadRdy[i]->wait(-1); outputBuffer.addFrom(0, startSample, m_ppAudioThread[i]->getBuffer(), 0, 0, numThisTime, 1.0); outputBuffer.addFrom(1, startSample, m_ppAudioThread[i]->getBuffer(), 1, 0, numThisTime, 1.0); } @@ -1460,28 +1485,30 @@ void JaySynthThread::run(void) { float *buf1, *buf2; + SynthDebug("Thread entry\n"); while(!threadShouldExit()) { - wait(-1); - if (threadShouldExit()) - break; - - m_buffer->clear (0, 0, m_sample_len); - m_buffer->clear (1, 0, m_sample_len); - - buf1 = m_buffer->getWritePointer (0, 0); - buf2 = m_buffer->getWritePointer (1, 0); - - for (int i = m_voice_offset; i < m_num_voices; i += m_voice_step) + if (wait(1000)) { - if (m_pVoices[i].state == note_state_idle) - continue; - VoiceProcessDataV(&m_pVoices[i], buf1, buf2, m_sample_len); + m_buffer->clear (0, 0, m_sample_len); + m_buffer->clear (1, 0, m_sample_len); + buf1 = m_buffer->getWritePointer (0, 0); + buf2 = m_buffer->getWritePointer (1, 0); + + for (int i = m_voice_offset; i < m_num_voices; i += m_voice_step) + { + if (m_pVoices[i].state == note_state_idle) + continue; + + VoiceProcessDataV(&m_pVoices[i], buf1, buf2, m_sample_len); + + } + m_pEventRdy->signal(); } - m_pEventRdy->signal(); } + SynthDebug("Thread exit\n"); } JaySynthThread::JaySynthThread(WaitableEvent *pEventRdy, voice_t *pVoices, int num_voices, int offset, int step) @@ -1494,13 +1521,16 @@ JaySynthThread::JaySynthThread(WaitableEvent *pEventRdy, voice_t *pVoices, int n m_voice_offset = offset; m_voice_step = step; m_buffer = new AudioSampleBuffer(2, SYNTH_MAX_BUFSIZE); - startThread (12); + m_sample_len = SYNTH_MAX_BUFSIZE; } void JaySynthThread::go(int len) { - m_sample_len = len; - notify(); + if (len <= SYNTH_MAX_BUFSIZE) + { + m_sample_len = len; + notify(); + } } AudioSampleBuffer& JaySynthThread::getBuffer(void) @@ -1510,7 +1540,6 @@ AudioSampleBuffer& JaySynthThread::getBuffer(void) JaySynthThread::~JaySynthThread() { - stopThread (100); - delete (m_buffer); +// delete (m_buffer); } //============================================================================== diff --git a/Source/JaySynth.h b/Source/JaySynth.h index bc13f00..dc1d68e 100644 --- a/Source/JaySynth.h +++ b/Source/JaySynth.h @@ -32,13 +32,12 @@ public: AudioSampleBuffer& getBuffer(void); void run(void); private: - AudioSampleBuffer *m_buffer; + ScopedPointer m_buffer; voice_t *m_pVoices; int m_num_voices; int m_voice_offset, m_voice_step; int m_sample_len; - ScopedPointer m_pEventRun; - ScopedPointer m_pEventRdy; + WaitableEvent *m_pEventRdy; }; @@ -245,7 +244,7 @@ private: midi_note_info_t last_midi_note_info; voice_t *m_pVoices; JaySynthThread **m_ppAudioThread; - ScopedPointer m_pEventAudioThreadRdy; + WaitableEvent **m_ppEventAudioThreadRdy; JaySynthMonophonicMGR m_monoMGR; uint32_t m_clockdiv; double m_lastTime_ms;