How to play more than one stream at once using soundio?

荒凉一梦 提交于 2021-02-11 08:07:38

问题


I'm new to soundio. I'm wondering how to play more than one audio source at once.

I'm looking to understand if I'm supposed to create several streams (seems wrong) and let the operating system do the mixing, or am I supposed to implement software mixing?

Software mixing seems tough too if my input sources are operating at different frequencies.

Am I basically asking "how to mix audio"?

I need a little direction.

Here's my use-case:

I have 5 different MP3 files. One is background music and the other 4 are sound effects. I want to start the background music and then play the sound effects as the user does something (such as click a graphical button). (This is for a game)


回答1:


You can create multiple streams and play them simultaneously. You don't need to do the mixing yourself. Anyway, it needs a lot of work.

Define WAVE_INFO and PLAYBACK_INFO:

struct WAVE_INFO
{
    SoundIoFormat format;
    std::vector<unsigned char*> data;
    int frames; // number of frames in this clip
}

struct PLAYBACK_INFO
{
    const WAVE_INFO* wave_info; // information of sound clip
    int progress; // number of frames already played
}
  1. Extract WAVE info out of sound clips and store them in an array of WAVE_INFO: std::vector<WAVE_INFO> waves_;. This vector is not going to change after being initialized.
  2. When you want to play waves_[index]:
SoundIoOutStream* outstream = soundio_outstream_create(sound_device_);
outstream->write_callback = write_callback;
PlayBackInfo* playback_info = new PlayBackInfo({&waves_[index], 0});
outstream->format = playback_info->wave_info->format;
outstream->userdata = playback_info;
soundio_outstream_open(outstream);
soundio_outstream_start(outstream);
std::thread stopper([this, outstream]()
{
    PlayBackInfo* playback_info = (PlayBackInfo*)outstream->userdata;
    while (playback_info->progress != playback_info->wave_info->frames)
    {
        soundio_wait_events(soundio_);
    }
    soundio_outstream_destroy(outstream);
    delete playback_info;
});
stopper.detach();
  1. In write_callback function:
PlayBackInfo* playback_info = (PlayBackInfo*)outstream->userdata;
int frames_left = playback_info->audio_info->frames - playback_info->progress;
if (frames_left == 0)
{
    soundio_wakeup(Window::window_->soundio_);
    return;
}
if (frames_left > frame_count_max)
{
    frames_left = frame_count_max;
}
// fill the buffer using
// soundio_outstream_begin_write and
// soundio_outstream_end_write by
// data in playback_info->wave_info.data
// considering playback_info->progress.

// update playback_info->progress based on
// number of frames are written to buffer

// for background music:
if (playback_info->audio_info->frames == playback_info->progress)
{
    // if application has not exited:
    playback_info->progress = 0;
}

Also this solution works, it needs lots of improvements. Please consider it as a POC only.



来源:https://stackoverflow.com/questions/64001616/how-to-play-more-than-one-stream-at-once-using-soundio

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!