×
Namespaces

Variants
Actions

如何在Qt应用中实现混音效果

From Nokia Developer Wiki
Jump to: navigation, search
Article Metadata

兼容于
平台:
Symbian

文章
renlin 在 09 Nov 2011 创建
最后由 kiran10182 在 31 Oct 2013 编辑


Contents

综述

在多媒体应用开发中,经常会遇到实现混音效果的问题,比如游戏开发中需要有背景音乐和特殊音效的同时播放,在Qt GameEnabler中提供一些类来帮助我们实现这种效果,本文将结合这些类和实例DJ Turntable来阐述如何在Qt应用中实现混音效果。

实现

可以从Qt GameEnabler的Audio Framwork来了解Qt GameEnabler如何搭建音频框架的。那么这个框架中对混音效果的实现呢,就是利用很多微小的时间片来播放不同的音乐,这些时间片连续起来的效果就如同几段音乐在同时播放一样,因为人的耳朵是感受不到那么微小的时间片内的差别的,为达到听觉上更顺畅的效果,用了多线程来进行分工。具体的实现就是通过继承自AudioSource的具体类来拉取数据,最后将这些数据在AudioMixer的pullAudio方法进行混合:

int AudioMixer::pullAudio(AUDIO_SAMPLE_TYPE *target ,int bufferLength)
{
QMutexLocker locker(&m_mutex);
 
if (m_sourceList.isEmpty())
return 0;
 
if (m_mixingBufferLength < bufferLength) {
if (m_mixingBuffer)
delete [] m_mixingBuffer;
 
m_mixingBufferLength = bufferLength;
m_mixingBuffer = new AUDIO_SAMPLE_TYPE[m_mixingBufferLength];
};
 
memset(target, 0, sizeof(AUDIO_SAMPLE_TYPE) * bufferLength);
 
AUDIO_SAMPLE_TYPE *t;
AUDIO_SAMPLE_TYPE *t_target;
AUDIO_SAMPLE_TYPE *s;
 
QList<AudioSource*>::iterator it = m_sourceList.begin();
while (it != m_sourceList.end()) {
//这里拉取数据..
int mixed = (*it)->pullAudio(m_mixingBuffer, bufferLength);
if (mixed > 0) {
// 这里开始混合..
t = target;
t_target = t + mixed;
s = m_mixingBuffer;
 
while (t != t_target) {
*t += (((*s) * m_fixedGeneralVolume) >> 12);
t++;
s++;
}
}
 
if ((*it)->canBeDestroyed()) {
// autodestroy
// NOTE, IS UNDER TESTING,... MIGHT CAUSE UNPREDICTABLE CRASHING
// WITH SOME USE CASES!!!
delete *it;
it = m_sourceList.erase(it);
}
else {
it++;
}
}
 
return bufferLength;
}

在实例DJ TurnTable中,迭代器it将会分别调用TurnTable 和DrumMachine的pullAudio方法,并将返回的m_mixingBuffer依次拷贝到目的缓冲区中,再由QIODevice的Write方法将最终的混合数据输出音频设备上:

m_outTarget->write((char*)m_sendBuffer,mixedSamples* 2);

可以参见实例DJ Turntable中的具体细节。

总结

Qt的多媒体框架并没有给我们提供直接可用的音频混合方法,Qt GameEnabler用底层的方法实现出了音频混合,这给我们开发这类应用的时候有了可供选择的一个方法,而且是比较好的一个选择。

相关链接

This page was last modified on 31 October 2013, at 23:01.
96 page views in the last 30 days.
×