ADLMIDI_EXPORT int adl_playFormat(ADL_MIDIPlayer *device, int sampleCount, ADL_UInt8 *out_left, ADL_UInt8 *out_right, const ADLMIDI_AudioFormat *format) { #if defined(ADLMIDI_DISABLE_MIDI_SEQUENCER) || defined(ADLMIDI_HW_OPL) ADL_UNUSED(device); ADL_UNUSED(sampleCount); ADL_UNUSED(out_left); ADL_UNUSED(out_right); ADL_UNUSED(format); return 0; #endif #if !defined(ADLMIDI_DISABLE_MIDI_SEQUENCER) && !defined(ADLMIDI_HW_OPL) sampleCount -= sampleCount % 2; //Avoid even sample requests if(sampleCount < 0) return 0; if(!device) return 0; MidiPlayer *player = GET_MIDI_PLAYER(device); assert(player); MidiPlayer::Setup &setup = player->m_setup; ssize_t gotten_len = 0; ssize_t n_periodCountStereo = 512; //ssize_t n_periodCountPhys = n_periodCountStereo * 2; int left = sampleCount; bool hasSkipped = setup.tick_skip_samples_delay > 0; while(left > 0) { {//... const double eat_delay = setup.delay < setup.maxdelay ? setup.delay : setup.maxdelay; if(hasSkipped) { size_t samples = setup.tick_skip_samples_delay > sampleCount ? sampleCount : setup.tick_skip_samples_delay; n_periodCountStereo = samples / 2; } else { setup.delay -= eat_delay; setup.carry += double(setup.PCM_RATE) * eat_delay; n_periodCountStereo = static_cast<ssize_t>(setup.carry); setup.carry -= double(n_periodCountStereo); } //if(setup.SkipForward > 0) // setup.SkipForward -= 1; //else { if((player->m_sequencer.positionAtEnd()) && (setup.delay <= 0.0)) break;//Stop to fetch samples at reaching the song end with disabled loop ssize_t leftSamples = left / 2; if(n_periodCountStereo > leftSamples) { setup.tick_skip_samples_delay = (n_periodCountStereo - leftSamples) * 2; n_periodCountStereo = leftSamples; } //! Count of stereo samples ssize_t in_generatedStereo = (n_periodCountStereo > 512) ? 512 : n_periodCountStereo; //! Total count of samples ssize_t in_generatedPhys = in_generatedStereo * 2; //! Unsigned total sample count //fill buffer with zeros int32_t *out_buf = player->m_outBuf; std::memset(out_buf, 0, static_cast<size_t>(in_generatedPhys) * sizeof(out_buf[0])); unsigned int chips = player->m_synth.m_numChips; if(chips == 1) { player->m_synth.m_chips[0]->generate32(out_buf, (size_t)in_generatedStereo); } else if(n_periodCountStereo > 0) { /* Generate data from every chip and mix result */ for(size_t card = 0; card < chips; ++card) player->m_synth.m_chips[card]->generateAndMix32(out_buf, (size_t)in_generatedStereo); } /* Process it */ if(SendStereoAudio(sampleCount, in_generatedStereo, out_buf, gotten_len, out_left, out_right, format) == -1) return 0; left -= (int)in_generatedPhys; gotten_len += (in_generatedPhys) /* - setup.stored_samples*/; } if(hasSkipped) { setup.tick_skip_samples_delay -= n_periodCountStereo * 2; hasSkipped = setup.tick_skip_samples_delay > 0; } else setup.delay = player->Tick(eat_delay, setup.mindelay); }//... } return static_cast<int>(gotten_len); #endif //ADLMIDI_DISABLE_MIDI_SEQUENCER }
ADLMIDI_EXPORT int adl_generateFormat(struct ADL_MIDIPlayer *device, int sampleCount, ADL_UInt8 *out_left, ADL_UInt8 *out_right, const ADLMIDI_AudioFormat *format) { #ifdef ADLMIDI_HW_OPL ADL_UNUSED(device); ADL_UNUSED(sampleCount); ADL_UNUSED(out_left); ADL_UNUSED(out_right); ADL_UNUSED(format); return 0; #else sampleCount -= sampleCount % 2; //Avoid even sample requests if(sampleCount < 0) return 0; if(!device) return 0; MidiPlayer *player = GET_MIDI_PLAYER(device); assert(player); MidiPlayer::Setup &setup = player->m_setup; ssize_t gotten_len = 0; ssize_t n_periodCountStereo = 512; int left = sampleCount; double delay = double(sampleCount) / double(setup.PCM_RATE); while(left > 0) { {//... const double eat_delay = delay < setup.maxdelay ? delay : setup.maxdelay; delay -= eat_delay; setup.carry += double(setup.PCM_RATE) * eat_delay; n_periodCountStereo = static_cast<ssize_t>(setup.carry); setup.carry -= double(n_periodCountStereo); { ssize_t leftSamples = left / 2; if(n_periodCountStereo > leftSamples) n_periodCountStereo = leftSamples; //! Count of stereo samples ssize_t in_generatedStereo = (n_periodCountStereo > 512) ? 512 : n_periodCountStereo; //! Total count of samples ssize_t in_generatedPhys = in_generatedStereo * 2; //! Unsigned total sample count //fill buffer with zeros int32_t *out_buf = player->m_outBuf; std::memset(out_buf, 0, static_cast<size_t>(in_generatedPhys) * sizeof(out_buf[0])); unsigned int chips = player->m_synth.m_numChips; if(chips == 1) player->m_synth.m_chips[0]->generate32(out_buf, (size_t)in_generatedStereo); else if(n_periodCountStereo > 0) { /* Generate data from every chip and mix result */ for(unsigned card = 0; card < chips; ++card) player->m_synth.m_chips[card]->generateAndMix32(out_buf, (size_t)in_generatedStereo); } /* Process it */ if(SendStereoAudio(sampleCount, in_generatedStereo, out_buf, gotten_len, out_left, out_right, format) == -1) return 0; left -= (int)in_generatedPhys; gotten_len += (in_generatedPhys) /* - setup.stored_samples*/; } player->TickIterators(eat_delay); }//... } return static_cast<int>(gotten_len); #endif }
OPNMIDI_EXPORT int opn2_play(OPN2_MIDIPlayer *device, int sampleCount, short *out) { if(!device) return 0; sampleCount -= sampleCount % 2; //Avoid even sample requests if(sampleCount < 0) return 0; if(device->QuitFlag) return 0; ssize_t gotten_len = 0; ssize_t n_periodCountStereo = 512; //ssize_t n_periodCountPhys = n_periodCountStereo * 2; int left = sampleCount; while(left > 0) { if(device->backup_samples_size > 0) { //Send reserved samples if exist ssize_t ate = 0; while((ate < device->backup_samples_size) && (ate < left)) { out[ate] = device->backup_samples[ate]; ate++; } left -= ate; gotten_len += ate; if(ate < device->backup_samples_size) { for(int j = 0; j < ate; j++) device->backup_samples[(ate - 1) - j] = device->backup_samples[(device->backup_samples_size - 1) - j]; } device->backup_samples_size -= ate; } else { const double eat_delay = device->delay < device->maxdelay ? device->delay : device->maxdelay; device->delay -= eat_delay; device->carry += device->PCM_RATE * eat_delay; n_periodCountStereo = static_cast<ssize_t>(device->carry); //n_periodCountPhys = n_periodCountStereo * 2; device->carry -= n_periodCountStereo; if(device->SkipForward > 0) device->SkipForward -= 1; else { std::vector<int16_t> out_buf; out_buf.resize(1024 /*n_samples * 2*/); ssize_t in_generatedStereo = (n_periodCountStereo > 512) ? 512 : n_periodCountStereo; ssize_t in_generatedPhys = in_generatedStereo * 2; //fill buffer with zeros size_t in_countStereoU = static_cast<size_t>(in_generatedStereo * 2); memset(out_buf.data(), 0, in_countStereoU * sizeof(short)); if(device->NumCards == 1) { (reinterpret_cast<OPNMIDIplay *>(device->opn2_midiPlayer))->opn.cardsOP2[0]->run(int(in_generatedStereo), out_buf.data()); /* Process it */ SendStereoAudio(device, sampleCount, in_generatedStereo, out_buf.data(), gotten_len, out); } else if(n_periodCountStereo > 0) { memset(out_buf.data(), 0, in_countStereoU * sizeof(short)); /* Generate data from every chip and mix result */ for(unsigned card = 0; card < device->NumCards; ++card) { (reinterpret_cast<OPNMIDIplay *>(device->opn2_midiPlayer))->opn.cardsOP2[card]->run(int(in_generatedStereo), out_buf.data()); } /* Process it */ SendStereoAudio(device, sampleCount, in_generatedStereo, out_buf.data(), gotten_len, out); } left -= in_generatedPhys; gotten_len += (in_generatedPhys) - device->stored_samples; } device->delay = reinterpret_cast<OPNMIDIplay *>(device->opn2_midiPlayer)->Tick(eat_delay, device->mindelay); } } return static_cast<int>(gotten_len); }