void AudioSoundIo::writeCallback(int frameCountMin, int frameCountMax) { const struct SoundIoChannelLayout *layout = &m_outstream->layout; SoundIoChannelArea *areas; int bytesPerSample = m_outstream->bytes_per_sample; int err; const float gain = mixer()->masterGain(); int framesLeft = frameCountMax; while (framesLeft > 0) { int frameCount = framesLeft; if ((err = soundio_outstream_begin_write(m_outstream, &areas, &frameCount))) { errorCallback(err); return; } if (!frameCount) break; for (int frame = 0; frame < frameCount; frame += 1) { if (m_outBufFrameIndex >= m_outBufFramesTotal) { m_outBufFramesTotal = getNextBuffer(m_outBuf); m_outBufFrameIndex = 0; } for (int channel = 0; channel < layout->channel_count; channel += 1) { float sample = gain * m_outBuf[m_outBufFrameIndex][channel]; memcpy(areas[channel].ptr, &sample, bytesPerSample); areas[channel].ptr += areas[channel].step; } m_outBufFrameIndex += 1; } if ((err = soundio_outstream_end_write(m_outstream))) { errorCallback(err); return; } framesLeft -= frameCount; } }
static void write_callback(struct SoundIoOutStream *outstream, int frame_count_min, int frame_count_max) { UNUSED(frame_count_min); double float_sample_rate = outstream->sample_rate; double seconds_per_frame = 1.0 / float_sample_rate; struct SoundIoChannelArea *areas; int err; int frames_left = frame_count_max; for (;;) { int frame_count = frames_left; if ((err = soundio_outstream_begin_write(outstream, &areas, &frame_count))) { fprintf(stderr, "unrecoverable stream error: %s\n", soundio_strerror(err)); exit(1); } if (!frame_count) break; const struct SoundIoChannelLayout *layout = &outstream->layout; double pitch = 440.0; double radians_per_second = pitch * 2.0 * PI; for (int frame = 0; frame < frame_count; frame += 1) { double sample = (float) sin((seconds_offset + frame * seconds_per_frame) * radians_per_second); for (int channel = 0; channel < layout->channel_count; channel += 1) { write_sample(areas[channel].ptr, sample); areas[channel].ptr += areas[channel].step; } } seconds_offset += seconds_per_frame * frame_count; if ((err = soundio_outstream_end_write(outstream))) { if (err == SoundIoErrorUnderflow) return; fprintf(stderr, "unrecoverable stream error: %s\n", soundio_strerror(err)); exit(1); } frames_left -= frame_count; if (frames_left <= 0) break; } soundio_outstream_pause(outstream, want_pause); }
//========AUDIO CALLBACK============= static void write_callback(struct SoundIoOutStream *outstream, int frame_count_min, int frame_count_max) { int frames_left = FRAME_COUNT;//frame_count_max; //int channels=outstream->layout.channel_count; //printf("min:%i max:%i\n",frame_count_min,frame_count_max); int err; struct SoundIoChannelArea *areas; while(frames_left>0) { int frame_count = frames_left; if((err = soundio_outstream_begin_write(outstream,&areas,&frame_count))) { printf("soundio_outstream_begin_write ERROR: %s",soundio_strerror(err)); exit(1); } if(!frame_count) break; for(int frame = 0; frame < frame_count; frame +=1) { int value1=0; int value2=0; int n=0; for(int i=0;i<MAX_POLYPHONY;i++) { if(playingsounds[i].sound!=NULL) { n++; value1 += playingsounds[i].sound->buffer[playingsounds[i].pos]*playingsounds[i].volume; value2 += playingsounds[i].sound->buffer[playingsounds[i].pos+1]*playingsounds[i].volume; playingsounds[i].pos+=2; if(playingsounds[i].pos>=playingsounds[i].sound->size) playingsounds[i].sound=NULL; } } short *ptr1=(short*)(areas[0].ptr + areas[0].step*frame); short *ptr2=(short*)(areas[1].ptr + areas[1].step*frame); if(n>0) { //if (n>10) printf("Poly:%i\n",n); *ptr1=(short)(value1/127); *ptr2=(short)(value2/127); } else { *ptr1=0; *ptr2=0; } } if ((err = soundio_outstream_end_write(outstream))) { printf("soundio_outstream_end_write ERROR: %s",soundio_strerror(err)); exit(1); } frames_left -= frame_count; } }
void SoundIoPlayer::write_callback(SoundIoOutStream* out, int frames_min, int frames_max) { // bug_fun(); // bug_var(frame_count_min); // bug_var(frame_count_max); // bug_var(out->userdata); // bug_var(out); auto& player = *reinterpret_cast<SoundIoPlayer*>(out->userdata); auto& audio = player.audio; channelnum_vec ons; // local versions to avoid (postpone) write lock // mt_clk::time_point cb_time; { audiogang::write_lock lock(audio.mtx); // 10th second auto samples = audio.rate / 10; player.pos = std::max(player.pos, player.reg.b); auto end = std::min(player.pos + samples, player.reg.e); wxThreadEvent evt(wxEVT_THREAD, ID_PlayerPos); evt.SetExtraLong(player.pos); player.frame.GetEventHandler()->QueueEvent(evt.Clone()); // reg = player.reg; // pos = player.pos; // cb_time = player.cb_time; // bug_var(player.pos); // bug_var(end); // bug_var(reg.b); // bug_var(reg.e); // copy valid channels that are on ons.reserve(audio.channels.size()); for(auto const& channel: audio.channels) if(channel.idx < audio.buffers.size()) ons.push_back(channel.idx); auto ons_size = ons.size(); // if(!ons_size) // return; SoundIoChannelArea* areas; int frames_left = frames_max; auto d = std::chrono::milliseconds(100); for(;;) { int frame_count = frames_left; int err; if((err = soundio_outstream_begin_write(out, &areas, &frame_count))) { logit("E: Unrecoverable Sound System Error: " << soundio_strerror(err)); // SoundIoPlayer::ctx_lock_guard lock(player.ctx_mtx); player.shutdown(); return; } if(!frame_count) break; SoundIoChannelLayout const* layout = &out->layout; for(int frame = 0; frame < frame_count && player.pos < end; ++frame, ++player.pos) { for(int c = 0; c < layout->channel_count; ++c) { auto sample = c < ons_size? audio.buffers[ons[c]][player.pos]: 0.0; player.write_sample(areas[c].ptr, sample); areas[c].ptr += areas[c].step; } } if(player.pos < player.reg.b) player.pos = player.reg.b; if(player.pos >= player.reg.e) { player.pos = player.reg.e; if(player.loop) player.pos = player.reg.b; else { // SoundIoPlayer::ctx_lock_guard lock(player.ctx_mtx); player.shutdown(); // player.ctx.reset(); return; } } // time_t timer = std::time(0); // bug("time: " << std::ctime(&timer)); // if(mt_clk::now() > cb_time) // { // player.play_event(ID_PlayerPos); // cb_time += d; // } if((err = soundio_outstream_end_write(out))) { if(err == SoundIoErrorUnderflow) return; logit("E: Unrecoverable Sound System Error: " << soundio_strerror(err)); // SoundIoPlayer::ctx_lock_guard lock(player.ctx_mtx); player.shutdown(); return; } frames_left -= frame_count; if(frames_left <= 0) break; } } // read lock // update: // audiogang::write_lock lock(audio.mtx); // player.pos = pos; // player.cb_time = cb_time; }