我想在我的Android手机上录制人声.我注意到Android有两个类来执行此操作:AudioRecord和MediaRecorder.有人能告诉我两者之间有什么区别,每种情况的适当用例是什么?
我希望能够实时分析人类语音以测量振幅等.我是否理解AudioRecord更适合此任务?
我注意到在官方Android 指南网页上录制音频,他们使用MediaRecorder而没有提及AudioRecord.
我想从麦克风录制音频并访问它以便近乎实时地播放.我不确定如何使用Android AudioRecord类来录制一些麦克风音频并快速访问它.
对于AudioRecord类,官方网站说'应用程序及时轮询AudioRecord对象','填充缓冲区的大小决定了在超载未读数据之前记录的时间长度'.后来建议在轮询频率较低时应使用更大的缓冲区.他们实际上从未在代码中显示示例.
我在书中看到的一个例子是使用AudioRecord类连续读取一个新填充了实时麦克风音频的缓冲区,然后应用程序将这些数据写入SD文件.伪代码看起来像 -
set up AudioRecord object with buffer size and recording format info
set up a file and an output stream
myAudioRecord.startRecording();
while(isRecording)
{
// myBuffer is being filled with fresh audio
read audio data into myBuffer
send contents of myBuffer to SD file
}
myAudioRecord.stop();
Run Code Online (Sandbox Code Playgroud)
这段代码如何将其读数与记录速率同步还不清楚 - 布尔"isRecording"是否在其他地方正确地打开和关闭?看起来这段代码可能过于频繁或过于频繁地读取,具体取决于读取和写入所需的时间.
网站doc还说AudioRecord类有一个名为OnRecordPositionUpdateListener的嵌套类,它被定义为一个接口.该信息表明,您以某种方式指定了您希望收到录制进度通知的时间段以及事件处理程序的名称,并且会以指定的频率自动调用您的事件处理程序.我认为伪代码中的结构会像 -
set target of period update message = myListener
set period to be about every 250 ms
other code
myListener()
{
if(record button was recently tapped)
handle …Run Code Online (Sandbox Code Playgroud) 我正在设计一个Android应用程序,我需要实现一个AudioRecord类来记录用户的声音.经过一些研究(没有提供足够的信息)和几次失败的尝试,我想知道是否有人可以通过发布关于如何使用AudioRecord捕获高质量声音的示例(代码)来帮助我.我真的很感激.谢谢
有没有办法记录Android中的麦克风输入,同时它是实时播放/预览的过程?我尝试使用AudioRecord和AudioTrack来做到这一点,但问题是我的设备无法播放录制的音频文件.实际上,任何Android播放器应用程序都无法播放录制的音频文件.
另一方面,使用Media.Recorder进行录制可以生成一个可以由任何播放器应用程序播放的良好录制的音频文件.但问题是我在实时录制麦克风输入时无法进行预览/播放.
任何反馈都非常感谢!提前致谢!
我目前正在尝试使用Android实现一些代码,以检测何时通过手机的麦克风播放多个特定的音频范围.我已经使用AudioRecord类设置了类:
int channel_config = AudioFormat.CHANNEL_CONFIGURATION_MONO;
int format = AudioFormat.ENCODING_PCM_16BIT;
int sampleSize = 8000;
int bufferSize = AudioRecord.getMinBufferSize(sampleSize, channel_config, format);
AudioRecord audioInput = new AudioRecord(AudioSource.MIC, sampleSize, channel_config, format, bufferSize);
Run Code Online (Sandbox Code Playgroud)
然后读入音频:
short[] audioBuffer = new short[bufferSize];
audioInput.startRecording();
audioInput.read(audioBuffer, 0, bufferSize);
Run Code Online (Sandbox Code Playgroud)
执行FFT是我陷入困境的地方,因为我在这方面的经验很少.我一直在尝试使用这个类:
然后我发送以下值:
Complex[] fftTempArray = new Complex[bufferSize];
for (int i=0; i<bufferSize; i++)
{
fftTempArray[i] = new Complex(audio[i], 0);
}
Complex[] fftArray = fft(fftTempArray);
Run Code Online (Sandbox Code Playgroud)
这可能很容易让我误解了这个课程是如何工作的,但是返回的值跳到了整个地方,即使在沉默中也不代表一致的频率.是否有人知道执行此任务的方法,或者我是否过于复杂化以尝试仅抓取少量频率范围而不是将其绘制为图形表示?
我正在使用AudioRecord在android中记录16位PCM数据.记录数据并将其保存到文件后,我将其读回以将其另存为.wav文件.
问题在于WAV文件被媒体播放器识别,但只能播放纯粹的噪音.我现在最好的猜测是我的wav文件头不正确,但我一直无法确定问题到底是什么.(我想这是因为我可以播放我在Audacity录制的原始PCM数据)
这是我的代码,用于读取原始PCM文件并将其保存为.wav:
private void properWAV(File fileToConvert, float newRecordingID){
try {
long mySubChunk1Size = 16;
int myBitsPerSample= 16;
int myFormat = 1;
long myChannels = 1;
long mySampleRate = 22100;
long myByteRate = mySampleRate * myChannels * myBitsPerSample/8;
int myBlockAlign = (int) (myChannels * myBitsPerSample/8);
byte[] clipData = getBytesFromFile(fileToConvert);
long myDataSize = clipData.length;
long myChunk2Size = myDataSize * myChannels * myBitsPerSample/8;
long myChunkSize = 36 + myChunk2Size;
OutputStream os;
os = new FileOutputStream(new File("/sdcard/onefile/assessor/OneFile_Audio_"+ newRecordingID+".wav"));
BufferedOutputStream bos = new BufferedOutputStream(os); …Run Code Online (Sandbox Code Playgroud) 我使用MediaCodecAndroid SDK提供的类,因为API级别16与OMX.SEC.aac.enc编码器一起将音频编码为文件.我从AudioRecord课堂上得到了音频输入.我的AudioRecord类实例配置如下:
bufferSize = AudioRecord.getMinBufferSize(44100, AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_16BIT);
recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, 44100, AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_DEFAULT, bufferSize);
Run Code Online (Sandbox Code Playgroud)
我能够从AudioRecord实例播放原始数据,因此问题不在那里.
我将AudioRecord实例的输出写入ByteBuffer实例并将其传递给编码器的可用输入缓冲区.编码器的输出被写入SD卡上的文件.
这些是我的MediaCodec实例的配置参数:
codec = MediaCodec.createEncoderByType("audio/mp4a-latm");
MediaFormat format = new MediaFormat();
format.setString(MediaFormat.KEY_MIME, "audio/mp4a-latm");
format.setInteger(MediaFormat.KEY_BIT_RATE, 64 * 1024);
format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 2);
format.setInteger(MediaFormat.KEY_SAMPLE_RATE, 44100);
format.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectHE);
codec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
Run Code Online (Sandbox Code Playgroud)
VLC告诉我,我的aac文件中没有流.该命令FFMPEG -i @filename@给出了以下错误:处理输入时找到无效数据.我测试过的所有媒体播放器都无法播放我的文件.
为什么我无法播放我的文件?我没有收到OpenMAX错误,LogCat应用程序在编码时不会崩溃.我写了一个视频编码器,它的工作原理与之相同.
这是将数据从AudioRecord实例读取到缓冲区的代码:
new Thread() {
public void run() { …Run Code Online (Sandbox Code Playgroud) 我正在努力实施
AudioRecord (MIC) ->
PCM -> AAC Encoder
AAC -> PCM Decode
-> AudioTrack?? (SPEAKER)
Run Code Online (Sandbox Code Playgroud)
与MediaCodec在Android 4.1+(API16).
首先,我成功(但不知道正确优化)实现PCM -> AAC Encoder由 MediaCodec为如下预期
private boolean setEncoder(int rate)
{
encoder = MediaCodec.createEncoderByType("audio/mp4a-latm");
MediaFormat format = new MediaFormat();
format.setString(MediaFormat.KEY_MIME, "audio/mp4a-latm");
format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
format.setInteger(MediaFormat.KEY_SAMPLE_RATE, 44100);
format.setInteger(MediaFormat.KEY_BIT_RATE, 64 * 1024);//AAC-HE 64kbps
format.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectHE);
encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
return true;
}
Run Code Online (Sandbox Code Playgroud)
INPUT:PCM比特率= 44100(Hz)x 16(比特)×1(等值)= 705600比特/秒
输出:AAC-HE比特率= 64 x 1024(比特)= 65536比特/秒
因此,数据大小近似被压缩x11,我通过观察日志确认了这一点
数据大小近似压缩x11,到目前为止一直很好.
现在,我有一个UDP服务器来接收编码数据,然后解码它.
解码器配置文件设置如下:
private …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用AudioRecord类来记录WAV文件.问题是它只提供原始PCM数据,如果我将其写入文件,则没有标题信息,因此它不会在任何媒体播放器中播放.如何从这些原始数据创建WAV文件?
或者,有没有其他方法将Android中的声音录制到WAV文件(或者MP3)?
哦,我知道MediaRecorder无法使用,因为它不支持WAV或MP3格式.
在我的Android应用程序中,我想从智能手机的麦克风中获取一些音频并立即播放,像麦克风一样直播,没有延迟.我目前正在考虑使用AudioRecord和AudioTrack类(从我读过的内容),但我不太确定如何继续.
我查看了Stack Overflow上的其他一些问题,但他们并没有完全回答我想做的事情.大多数是2012年.
那么如何使用这些类同时输入和输出音频呢?
另外:我看了一下MediaRecorder API,但是根据我的阅读,需要你将音频保存到文件中,我不想这样做.可以通过tweek来满足我的要求吗?或者我最好只使用AudioRecord?
谢谢
编辑:
以下是我在@Pradip Pramanick建议的更新代码:
final Thread record = new Thread(new Runnable() {
@Override
public void run() {
while (!Thread.interrupted()) {
MediaRecorder microphone = new MediaRecorder();
microphone.setAudioSource(MediaRecorder.AudioSource.MIC);
microphone.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
microphone.setOutputFile(filename);
microphone.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
try {
microphone.prepare();
} catch (IOException e) {
e.printStackTrace();
}
microphone.start();
}
}
});
final Thread play = new Thread(new Runnable() {
@Override
public void run() {
while (!Thread.interrupted()) {
player = new MediaPlayer();
try { …Run Code Online (Sandbox Code Playgroud) android ×10
audiorecord ×10
audio ×4
java ×3
pcm ×3
aac ×2
mediacodec ×2
wav ×2
audiotrack ×1
fft ×1
frequency ×1
microphone ×1
openmax ×1