我正试图从我的Android Wear手表中获取音量:MOTO 360。 但是,我只能从Audiorecord.read获得0个PCM值。
我在一个单独的线程中运行记录过程。下面是我的代码的摘录,你知道我做错了吗?
非常感谢你的帮助
JN。
REREDIT:MOTO的新结果。看起来真的很奇怪!
03-15 20:38:08.740 1420-3994 /? W / mot_vr_audio_hw:由于DSP被禁用,因此不允许唤醒()
重新编辑:我用不同的WATCH(Sony)尝试了我的代码。日志更明确
03-08 22:11:40.342 1165-1650 /? D / MICRO:将以44100Hz的速度记录15052缓冲区
03-08 22:11:40.343 153-153 /? E / AudioPolicyManager:startInput(21)失败:其他输入19已经启动
03-08 22:11:40.343 1165-1650 /? E / AudioRecord:start()状态-38
当2个audiorecord对象同时处于活动状态时,似乎会触发此错误。但我很确定我的只开始一次。你认为它可能是一个系统Audiorecord对象,阻止我的发射?
编辑:我的穿着清单中确实有这个 uses-permission android:name =" android.permission.RECORD_AUDIO"private int sampleRateInHz = 8000;
private int channelConfig = AudioFormat.CHANNEL_IN_MONO;
private int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
public void run(){
running=true;
bufferSize = AudioRecord.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat);
recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,sampleRateInHz, channelConfig, audioFormat, bufferSize);
Log.d(TAG,"WILL RECORD AT "+sampleRateInHz+"Hz IN A BUFFER OF "+bufferSize);
recording=true;
try{
while (recording){
if ((recorder.getState()==android.media.AudioRecord.STATE_INITIALIZED)&&(recorder.getRecordingState()==android.media.AudioRecord.RECORDSTATE_STOPPED)){
recorder.startRecording();
Log.d(TAG,"START RECORDING DUDE");
}
int theVolume = getVolume(sampleRateInHz, bufferSize);
Thread.sleep(10);
}
if (!recording){
Thread.currentThread().interrupt();
Log.d(TAG,"MIC THREAD STOPPED");
}
}catch (InterruptedException e){
e.printStackTrace();
}
private int getVolume(int sampleRate, int bufferSize){
short[] audioData = new short [bufferSize];
int nbOfSamples = recorder.read(audioData,0,bufferSize);
int numSamples = audioData.length;
int numCrossing = 0;
double volume = 0;
for (int p = 0; p < numSamples-1; p++){
volume += audioData[p]*audioData[p];
}
Log.d(TAG,"volume from pcm: "+volume);
volume = Math.sqrt(volume/nbOfSamples);
currentVolume = (int) (0.5*currentVolume+ 0.5*volume);
Log.d(TAG,"currentVolume: "+currentVolume);
return currentVolume;
}
答案 0 :(得分:1)
您的更多代码会有所帮助。但听起来麦克风已经在使用中。我也遇到了一些问题。如果您在一个线程中运行它,您可能会意外地启动多个线程。此外,如果您在服务中运行此功能,则可能会启动多项服务。现在,如果您进行Google搜索,“可以运行同一服务的多个实例”,您会发现很多人拒绝。但事实是肯定的,您可以同时运行同一服务的多个实例。我的建议是Log.d
每个记录循环上的一个随机数。确保一次只有一个线程正在工作
public void run(){
int randThreadNumber = randInt(0,100);
while (recording) {
Log.d("MYTAG", "Rand number " + randThreadNumber);
..........more code.............
}
..........more code.............
}
public static int randInt(int min, int max) {
Random rand = new Random();
int randomNum = rand.nextInt((max - min) + 1) + min;
return randomNum;
}
另一件可能导致您无法访问Android Wear上的录音机的事情是,如果手表正在收听“OK Google”,那么如果您尝试在手表处于响应“OK”的状态下捕获音频谷歌“音频记录不起作用。
这是查看麦克风是否可用的好方法
while(recording)
{
readResult = audio_recorder.read(buf, 0, buf.length);
//See if read worked
if(readResult != -3) {
// yay it worked. Do stuff
} else {
// if result is -3 then the watch's mic was inaccessible, wait then retry
Log.d(TAG, "Waiting for Watch to give up Microphone");
try {
Thread.sleep(100, 0);
audio_recorder.startRecording(); // restart audio recording
} catch(Exception e) {
Log.e(TAG, "exception", e); // Error trying to sleep thread
}
}
}
编辑在每次读取调用之间调用Thread.sleep(10);
也没用,因为read方法正在阻塞。如果它没有提供任何东西,它将等待,然后在准备就绪时返回。