在 Android 中播放立体声
关于这个问题的类似主题包括仅在左右频率相同的单声道中播放音调。
我的问题是:如何生成立体声,使左声道的频率与右声道的频率不同?
我想过预先录制 .wav 文件,但录制许多 .wav 文件并将其放在 res 文件夹中并不是一个好主意。
我遇到了 SoundPool
和 AudioTrack
类,但我需要一个片段,显示在播放音调之前存储为缓冲区的左声道和右声道的不同频率。
或者还有其他方法吗?请提供所需的片段。
Similar topics on this question include only playing tone in mono where the left and right frequencies are the same.
My question is: how to generate a stereo tone such that the left channel has a different frequency than the right channel?
I thought of pre-recording .wav files but recording many .wav files and putting it on res folder is not a good idea.
i come across the SoundPool
and AudioTrack
class but I need a snippet showing the different frequencies of the left and right channel stored as buffer before playing the tone.
Or is there other ways? Please provide the desired snippet.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我会使用其他软件生成 .ogg 立体声文件(不要使用 WAV 文件,它们太重了),这是一种非常轻量级的音频格式,在 Android 中运行良好。我使用免费的 Reaper,Audacity 更容易,任何人都会做。只需创建两个单声道音轨,将其平移设置为最右和最左。加载您的样本,并应用音高变化插件来改变其中一首曲目的频率。您还可以使用合成器生成它们。然后将所有内容渲染到tone.ogg 文件中。
音调
I would use other software to generate an .ogg stereo file (don't use WAV files, they weight too much), wich is a very lightweight audio format wich works well in Android. I use the free Reaper, Audacity is easier, anyone would do. Just create two mono audio tracks, set their pan to full right and full left. Load your samples, and apply a pitch-change plugin to alter the frequency of one of the tracks. You can also generate them with a sintesizer. Then render all to a tone.ogg file.
Tone
我从来没有尝试过这个:
初始化你的左右频率
//播放速率(1.0=正常播放,范围0.5到2.0)
float lFrequency = 1.0;
float rFrequency = 1.0;
初始化 SoundPool< /a> 对象
SoundPool sp = SoundPool(2, AudioManager.STREAM_MUSIC, 0);
加载曲目两次 (加载函数)
int sLeft = sp.load(mContext, R.raw.yourAudioFileId, 1);
int sRight = sp.load(mContext, R.raw.yourAudioFileId, 1);
使用不同的速率(播放功能)
sp.play(sLeft, 1.0, 0.0, 0, 0, lFrequency);
sp.play (sRight, 0.0, 1.0, 0, 0, rFrequency);
I have never tried this:
Initialize your left and right frequencies
//playback rate (1.0 = normal playback, range 0.5 to 2.0)
float lFrequency = 1.0;
float rFrequency = 1.0;
Initialize a SoundPool object
SoundPool sp = SoundPool(2, AudioManager.STREAM_MUSIC, 0);
Load your track twice (load function)
int sLeft = sp.load(mContext, R.raw.yourAudioFileId, 1);
int sRight = sp.load(mContext, R.raw.yourAudioFileId, 1);
Play the 2 sounds (one on Left and one on Right) using different rates (play function)
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 单声道或立体声流”
因此,只要您播放的文件一开始就是立体声,它就应该以这种方式播放。
From my understanding, if you use SoundPool it will play in stereo without any special configuration. From the documentation: "The SoundPool library uses the MediaPlayer service to decode the audio into a raw 16-bit PCM mono or stereo stream"
so as long as the file you play is in Stereo to begin with, it should play that way.
您可以从代码在内存中生成分通道 WAV 音频,然后将其保存为您将使用 SoundPool 播放的 WAV 文件,或者直接使用 AudioTrack 播放音频,而不是预先录制 WAV 文件并将其嵌入到您的应用程序中(我推荐后者)。
音频本身只是一个(通常)2 字节整数的数组。对于立体声,左右样本在整个阵列中交错(因此样本 [0] 是第一个 L 样本,样本 [1] 是第一个 R 样本,样本 [2] 是第二个 L 样本等)。因此,当您的应用程序启动时,您可以创建一个数组,无论您需要多长时间(对于 CD 质量的音频,您的数组将需要每秒音频 88200 个元素),然后用计算出的音调值填充样本,然后传递该数组到 AudioTrack 进行播放。
或者您可以将音频保存为 WAV 文件并使用 SoundPool 播放它(从内存占用的角度来看,这实际上可能更好)。 WAV 格式的写入非常简单(读取更复杂):只需一个具有各种属性的 44 字节标头,然后是音频数据本身。
我想我之前已经回答过类似的android问题,所以我要去看看我是否有一些基本的代码来做到这一点。
不是我,而是一些用 java 读写 WAV 文件的好代码:
Instead of prerecording WAV files and embedding them in your application, you can instead generate the split-channel WAV audio in memory from code, and then either save it as a WAV file that you would play with SoundPool, or play the audio directly using AudioTrack (I'd recommend the latter).
The audio itself is just an array of (usually) 2-byte integers. With stereo, the left and right samples are interleaved throughout the array (so sample[0] is the first L sample, sample[1] is the first R sample, sample[2] is the second L sample etc.). So when your app starts up, you would create an array however long you need (with CD-quality audio, your array will need 88200 elements for each second of audio) then fill the samples with calculated values for your tone, then pass the array to AudioTrack for playing.
Or you would save the audio as a WAV file and play it with SoundPool (which might actually be better from a memory footprint standpoint). The WAV format is very simple to write (reading is more complicated): just a 44-byte header with various properties, and then the audio data itself.
I think I've answered a similar android question before, so I'm going to go see if I have some basic code for doing this.
Not me, but some good code for reading and writing WAV files in java:
http://computermusicblog.com/blog/2008/08/29/reading-and-writing-wav-files-in-java