【问题标题】:How to play more than one stream at once using soundio?如何使用 soundio 一次播放多个流?
【发布时间】:2020-10-17 13:15:41
【问题描述】:

我是 soundio 的新手。我想知道如何一次播放多个音频源。

我想了解是否应该创建多个流(似乎是错误的)并让操作系统进行混合,还是应该实现软件混合?

如果我的输入源在不同频率下运行,软件混音似乎也很困难。

我基本上是在问“如何混合音频”吗?

我需要一点方向。

这是我的用例:

我有 5 个不同的 MP3 文件。一个是背景音乐,另外四个是音效。我想开始播放背景音乐,然后在用户执行某些操作(例如单击图形按钮)时播放音效。 (这是为了游戏)

【问题讨论】:

  • 你能用“soundio”标记你的问题吗?

标签: audio


【解决方案1】:

您可以创建多个流并同时播放它们。您不需要自己进行混合。无论如何,它需要做很多工作。

定义WAVE_INFOPLAYBACK_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. 从声音片段中提取 WAVE 信息并将它们存储在 WAVE_INFO:std::vector&lt;WAVE_INFO&gt; waves_; 的数组中。这个向量在初始化后不会改变。
  2. 当你想玩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. write_callback函数中:
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;
}

此解决方案也有效,但需要大量改进。请仅将其视为 POC。

【讨论】:

    猜你喜欢
    • 2014-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多