【发布时间】:2012-01-18 15:54:00
【问题描述】:
关于这个问题的类似主题包括只播放左右频率相同的单声道。
我的问题是:如何生成立体声,使左声道的频率与右声道不同?
我想过预先录制 .wav 文件,但录制许多 .wav 文件并将其放在 res 文件夹中并不是一个好主意。
我遇到了 SoundPool 和 AudioTrack 类,但我需要一个 sn-p 显示在播放音调之前存储为缓冲区的左右声道的不同频率。
或者还有其他方法吗?请提供所需的 sn-p。
【问题讨论】:
关于这个问题的类似主题包括只播放左右频率相同的单声道。
我的问题是:如何生成立体声,使左声道的频率与右声道不同?
我想过预先录制 .wav 文件,但录制许多 .wav 文件并将其放在 res 文件夹中并不是一个好主意。
我遇到了 SoundPool 和 AudioTrack 类,但我需要一个 sn-p 显示在播放音调之前存储为缓冲区的左右声道的不同频率。
或者还有其他方法吗?请提供所需的 sn-p。
【问题讨论】:
我从未尝试过:
初始化左右频率//playback rate (1.0 = normal playback, range 0.5 to 2.0)float lFrequency = 1.0;float rFrequency = 1.0;
初始化SoundPool对象SoundPool sp = SoundPool(2, AudioManager.STREAM_MUSIC, 0);
加载您的曲目两次 (load function)int sLeft = sp.load(mContext, R.raw.yourAudioFileId, 1);int sRight = sp.load(mContext, R.raw.yourAudioFileId, 1);
使用不同的速率 (play function) 播放 2 个声音(一个在左侧,一个在右侧)sp.play (sLeft, 1.0, 0.0, 0, 0, lFrequency);sp.play (sRight, 0.0, 1.0, 0, 0, rFrequency);
【讨论】:
据我了解,如果您使用 SoundPool,它会以立体声播放,无需任何特殊配置。来自文档:“SoundPool 库使用 MediaPlayer 服务将音频解码为原始 16 位 PCM 单声道或立体声流” 因此,只要您播放的文件一开始是立体声的,它就应该以这种方式播放。
【讨论】:
除了预先录制 WAV 文件并将它们嵌入到您的应用程序中,您还可以从代码在内存中生成分离通道 WAV 音频,然后将其保存为您可以使用 SoundPool 播放的 WAV 文件,或者播放音频直接使用 AudioTrack(我推荐后者)。
音频本身只是(通常)2 字节整数的数组。对于立体声,左右样本在整个阵列中交错(因此 sample[0] 是第一个 L 样本,sample[1] 是第一个 R 样本,sample[2] 是第二个 L 样本等)。因此,当您的应用程序启动时,您将创建一个数组,无论您需要多长时间(对于 CD 质量的音频,您的数组将需要 88200 个元素来处理每一秒的音频),然后用计算出的音调值填充样本,然后传递数组到 AudioTrack 播放。
或者您可以将音频保存为 WAV 文件并使用 SoundPool 播放(从内存占用的角度来看,这实际上可能更好)。 WAV 格式写起来很简单(读起来更复杂):只是一个 44 字节的头部,具有各种属性,然后是音频数据本身。
我想我以前回答过一个类似的android问题,所以我要去看看我是否有一些基本的代码来做这个。
不是我,而是一些用java读写WAV文件的好代码:
http://computermusicblog.com/blog/2008/08/29/reading-and-writing-wav-files-in-java
【讨论】:
我会使用其他软件来生成 .ogg 立体声文件(不要使用 WAV 文件,它们的重量太大),这是一种非常轻量级的音频格式,在 Android 中运行良好。我使用免费的 Reaper,Audacity 更容易,任何人都会这样做。只需创建两个单声道音轨,将它们的平移设置为全右和全左。加载你的样本,并应用一个音高改变插件来改变其中一个轨道的频率。您也可以使用 sintesizer 生成它们。然后将所有内容渲染到一个tone.ogg 文件。 Tone
【讨论】: