fluidsynth修改midi播放的通道为ring
在前面一篇文章中,记录了FluidSynth编译的各种小坑。现在进行一个实践操作。修改midi播放通道为ring
fluidsynth中用于播放声音的库由很多,即,audio.driver有很多,默认是oboe的。现在我们希望当midi播放时,选在opensles作为播放驱动。并将其声音,该为ring通道。
查看代码可以知道,opensles的创建在文件:/src/drivers/fluid_opensles.c文件中。
翻越android NDK文档,关于OPENGLES的介绍,点击此处查看
在CreateAudioPlayer之后,realize之前,进行声音通道的配置。
结合fluid_opensles.c文件中的结构,在fluid_opensles_audio_driver_t结构体中,增加如下代码:
typedef struct
{
fluid_audio_driver_t driver;
SLObjectItf engine;
SLObjectItf output_mix_object;
SLObjectItf audio_player;
SLPlayItf audio_player_interface;
SLAndroidSimpleBufferQueueItf player_buffer_queue_interface;
SLAndroidConfigurationItf playerConfig;//注意,此处是我们增加的代码,看看命名规范的差异
void *synth;
int period_frames;
int is_sample_format_float;
/* used only by callback mode */
short *sles_buffer_short;
float *sles_buffer_float;
int cont;
double sample_rate;
} fluid_opensles_audio_driver_t;
然后在创建player时,指示需要配置接口,因此,修改如下代码:
const SLInterfaceID ids1[] = {
SL_IID_ANDROIDCONFIGURATION,SL_IID_ANDROIDSIMPLEBUFFERQUEUE};
const SLboolean req1[] = {
SL_BOOLEAN_TRUE,SL_BOOLEAN_TRUE };
result = (*engine_interface)->CreateAudioPlayer(engine_interface,
&(dev->audio_player), &audio_src, &audio_sink, 2, ids1, req1);
即ids1和req1数组,分别增加SL_IID_ANDROIDCONFIGURATION,SL_BOOLEAN_TRUE。否则后面无法获取到正确的配置对象。
现在player支持配置了,那么接下来就是进行配置,配置一个发生在Realize调用之前。因此在Realize调用前增加如下代码:
// Force the use of the ring
//获取配置对象
result = (*dev->audio_player)->GetInterface(dev->audio_player,
SL_IID_ANDROIDCONFIGURATION, &(dev->playerConfig));
if(result != SL_RESULT_SUCCESS)
{
goto error_recovery;
}
//修改配置
SLint32 streamType = SL_ANDROID_STREAM_RING;
result = (*dev->playerConfig)->SetConfiguration(dev->playerConfig,
SL_ANDROID_KEY_STREAM_TYPE,&streamType, sizeof(SLint32));
if(result != SL_RESULT_SUCCESS)
{
goto error_recovery;
}
至此,一切修改完毕,重新编译,放入app中,即可运行。现在我的midi播放器可以通过ring通道来调节音量,而mp3可以通过media通道来调节音量了。
为了便于有需要的伙伴,现将所有代码附上,见链接点击此处