如何实现一个多通道音频预混合器.net
问题描述:
我想用C#来实现一个可以同时播放多个音频流的应用程序。花生 - 现在有趣的部分:假设每个流都是单声道(单声道),我想为每个流分别调整每个扬声器的音量(5.1甚至7.1)。我可以使用Windows混音器来做到这一点,但问题是,只有一个混音器,我想单独调整每个流。任何想法如何实现这一点?如何实现一个多通道音频预混合器.net
我的第一个猜测是将流多路复用八次(7.1),对每个“通道”应用音量电平,然后将其发送到窗口混音器,例如对于80%的所有通道均匀混音。你知道任何可能支持这种用例的库吗?
AFAIK低音和fmod不能做到这一点,但纠正我,如果我错了。作为另一种选择,我正在考虑对XNA进行黑客攻击:使用一个向量来描述与侦听器相关的流的位置,并使用它来应用音量补偿......只是ramblings。
(请不要点我这方面的一些C++/WinAPI的想法,这个项目是不是值得我们学习另一种语言。)
答
终于得到它:bass.dll允许应用矩阵分别使用方法BassMix.BASS_Mixer_ChannelSetMatrix(int streamHandle, float[,] volumeMatrix)
为每个扬声器设定音量。您可以看到一个示例here,他们正在使用它将立体声流上混为四个扬声器。低于我创建的完整课程来解决我的问题。
public class SeparateVolumeLevelPlayer : IDisposable
{
private readonly int outputMixerStream;
private readonly int inputStream;
private readonly int numberOfSpeakers;
public SeparateVolumeLevelPlayer(string fileName, int numberOfSpeakers)
{
this.numberOfSpeakers = numberOfSpeakers;
outputMixerStream = BassMix.BASS_Mixer_StreamCreate(44100, numberOfSpeakers, BASSFlag.BASS_MIXER_MATRIX);
ThrowOnError();
// create a stream from the media file
inputStream = Bass.BASS_StreamCreateFile(fileName, 0L, 0L, BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_MIXER_MATRIX | BASSFlag.BASS_SAMPLE_MONO);
ThrowOnError();
// add the stream to the mixer
BassMix.BASS_Mixer_StreamAddChannel(outputMixerStream, inputStream, BASSFlag.BASS_MIXER_MATRIX);
ThrowOnError();
}
public void Play()
{
// start playback of the mixed streams
Bass.BASS_ChannelPlay(outputMixerStream, false);
ThrowOnError();
}
public void SetVolume(float[] volumeValues)
{
if (volumeValues == null)
{
throw new ArgumentNullException("volumeValues");
}
if (volumeValues.Length != numberOfSpeakers)
{
string message =
string.Format("You must pass a volume level for every speaker. You provided {0} values for {1} speakers",
volumeValues.Length, numberOfSpeakers);
throw new ArgumentException(message);
}
var volumeMatrix = new float[numberOfSpeakers, 1];
for (int i = 0; i < numberOfSpeakers; i++)
{
volumeMatrix[i, 0] = volumeValues[i];
}
// adjust the volume using the matrix
BassMix.BASS_Mixer_ChannelSetMatrix(inputStream, volumeMatrix);
ThrowOnError();
}
private static void ThrowOnError()
{
BASSError err = Bass.BASS_ErrorGetCode();
if (err != BASSError.BASS_OK)
{
throw new ApplicationException(string.Format("bass.dll reported {0}.", err));
}
}
public void Dispose()
{
Bass.BASS_StreamFree(inputStream);
Bass.BASS_StreamFree(outputMixerStream);
}
}
也许一个想法刚刚到达我的大脑:要求将可用的声音文件导入并最初转码为一种声音库是完全可以的。 vorbis格式支持多达255个通道,并有一个(可能被放弃的)lib可用:http://vorbisdotnet.sourceforge.net/ – 2009-10-26 15:10:50
有点碰撞:我在Codeplex上找到了NAudio库。好东西... – 2009-10-27 10:59:30