如何使用soundio一次播放多个流? [英] How to play more than one stream at once using soundio?

查看:75
本文介绍了如何使用soundio一次播放多个流?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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"?

我需要一点指导.

这是我的用例:

我有5个不同的MP3文件.一种是背景音乐,另一种是声音效果.我想启动背景音乐,然后在用户执行某些操作(例如单击图形按钮)时播放声音效果.(这是一个游戏)

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)

推荐答案

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

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.

定义 WAVE_INFO 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. 从声音片段中提取WAVE信息,并将其存储在 WAVE_INFO 的数组中: std :: vector< WAVE_INFO>wave _; .此向量在初始化后将不会更改.
  2. 要播放 waves_ [index] :
  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. 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.

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

这篇关于如何使用soundio一次播放多个流?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆