如何在B4A中实现左右声道分别播放不同频率音频?
解决B4A音频左右声道分离播放问题
要实现左、右声道分别播放不同频率,首先要确保AudioStreamer初始化时启用立体声模式,然后修改音频采样数据的写入逻辑,对应到左右声道的字节位置。
一、前提:初始化立体声AudioStreamer
在使用streamer1前,必须以立体声模式初始化(第三个参数设为True):
streamer1.Initialize("streamer1", 8000, True, 16, 1000)
参数说明:8000是采样率,True表示立体声,16是位深度,1000是缓冲区大小。
二、修改双频率声道分离代码(GenBB)
原代码将左右声道采样混合写入,现在需要分别写入左、右声道的对应字节位置。立体声的每个采样帧包含左声道2字节 + 右声道2字节,因此数组长度需改为4 * Samples:
Public Sub GenBB (DurationMs As Double, FreqLeft As Double, FreqRight As Double) Dim Samples As Int = 8000 * DurationMs / 1000 ' 立体声每个采样帧占4字节(左2字节+右2字节),总长度为4*Samples Dim Tone(4 * Samples) As Byte For i = 0 To Samples - 1 ' 计算左、右声道的16位采样值(范围-16384到16383) Dim sampleLeft As Double = Sin(2 * cPI * i / (8000 / FreqLeft)) * 16383.5 Dim sampleRight As Double = Sin(2 * cPI * i / (8000 / FreqRight)) * 16383.5 ' 写入左声道的低字节和高字节 Tone(4 * i + 0) = Bit.And(sampleLeft, 0x00ff) Tone(4 * i + 1) = Bit.UnsignedShiftRight(Bit.And(sampleLeft, 0xff00), 8) ' 写入右声道的低字节和高字节 Tone(4 * i + 2) = Bit.And(sampleRight, 0x00ff) Tone(4 * i + 3) = Bit.UnsignedShiftRight(Bit.And(sampleRight, 0xff00), 8) Next streamer1.Write(Tone) End Sub
三、单一频率指定声道播放(GenerateTone)
新增一个参数指定目标声道,对应声道写入采样值,另一个声道写入0(静音):
' LeftChannel为True时播放到左声道,False时播放到右声道 Public Sub GenerateTone (DurationMs As Double, Frequency As Double, LeftChannel As Boolean) Dim Samples As Int = 8000 * DurationMs / 1000 Dim Tone(4 * Samples) As Byte For i = 0 To Samples - 1 Dim Sample As Double = Sin(2 * cPI * i / (8000 / Frequency)) * 16383.5 If LeftChannel Then ' 左声道写入采样,右声道写0 Tone(4 * i + 0) = Bit.And(Sample, 0x00ff) Tone(4 * i + 1) = Bit.UnsignedShiftRight(Bit.And(Sample, 0xff00), 8) Tone(4 * i + 2) = 0 Tone(4 * i + 3) = 0 Else ' 右声道写入采样,左声道写0 Tone(4 * i + 0) = 0 Tone(4 * i + 1) = 0 Tone(4 * i + 2) = Bit.And(Sample, 0x00ff) Tone(4 * i + 3) = Bit.UnsignedShiftRight(Bit.And(Sample, 0xff00), 8) End If Next streamer1.Write(Tone) End Sub
关键逻辑说明
- 16位音频的每个采样值占2字节,低字节在前、高字节在后(小端格式),通过
Bit.And和Bit.UnsignedShiftRight拆分字节。 - 立体声的字节数组按左低→左高→右低→右高的顺序循环排列,每个采样帧占用4字节空间。
内容的提问来源于stack exchange,提问作者Hedi
相关产品推荐
相关产品推荐

