gpt4 book ai didi

android - 在android中检测 'WhiSTLe'声音

转载 作者:行者123 更新时间:2023-11-29 14:52:12 25 4
gpt4 key购买 nike

我想检测“哨子”的声音。为此,我实现了 http://code.google.com/p/musicg/

源代码本身有问题。当您启动应用程序时,它已准备好收听,但当您返回并再次重新启动检测器线程时,它不会触发哨声检测。

检测线程.java

package weetech.wallpaper.services;

import java.util.LinkedList;

import weetech.wallpaper.utils.Debug;
import android.media.AudioFormat;
import android.media.AudioRecord;

import com.musicg.api.WhistleApi;
import com.musicg.wave.WaveHeader;

public class DetectorThread extends Thread {

private RecorderThread recorder;
private WaveHeader waveHeader;
private WhistleApi whistleApi;
private Thread _thread;

private LinkedList<Boolean> whistleResultList = new LinkedList<Boolean>();
private int numWhistles;
private int totalWhistlesDetected = 0;
private int whistleCheckLength = 3;
private int whistlePassScore = 3;

public DetectorThread(RecorderThread recorder) {
this.recorder = recorder;
AudioRecord audioRecord = recorder.getAudioRecord();

int bitsPerSample = 0;
if (audioRecord.getAudioFormat() == AudioFormat.ENCODING_PCM_16BIT) {
bitsPerSample = 16;
} else if (audioRecord.getAudioFormat() == AudioFormat.ENCODING_PCM_8BIT) {
bitsPerSample = 8;
}

int channel = 0;
// whistle detection only supports mono channel
if (audioRecord.getChannelConfiguration() == AudioFormat.CHANNEL_IN_MONO) {
channel = 1;
}

waveHeader = new WaveHeader();
waveHeader.setChannels(channel);
waveHeader.setBitsPerSample(bitsPerSample);
waveHeader.setSampleRate(audioRecord.getSampleRate());
whistleApi = new WhistleApi(waveHeader);
}

private void initBuffer() {
numWhistles = 0;
whistleResultList.clear();

// init the first frames
for (int i = 0; i < whistleCheckLength; i++) {
whistleResultList.add(false);
}
// end init the first frames
}

public void start() {
_thread = new Thread(this);
_thread.start();
}

public void stopDetection() {
_thread = null;
}

@Override
public void run() {
Debug.e("", "DetectorThread started...");

try {
byte[] buffer;
initBuffer();

Thread thisThread = Thread.currentThread();
while (_thread == thisThread) {
// detect sound
buffer = recorder.getFrameBytes();

// audio analyst
if (buffer != null) {
// sound detected
// MainActivity.whistleValue = numWhistles;

// whistle detection
// System.out.println("*Whistle:");

try {
boolean isWhistle = whistleApi.isWhistle(buffer);
Debug.e("", "isWhistle : " + isWhistle + " "
+ buffer.length);

if (whistleResultList.getFirst()) {
numWhistles--;
}

whistleResultList.removeFirst();
whistleResultList.add(isWhistle);

if (isWhistle) {
numWhistles++;
}

// Debug.e("", "numWhistles : " + numWhistles);

if (numWhistles >= whistlePassScore) {
// clear buffer
initBuffer();
totalWhistlesDetected++;

Debug.e("", "totalWhistlesDetected : "
+ totalWhistlesDetected);

if (onWhistleListener != null) {
onWhistleListener.onWhistle();
}
}
} catch (Exception e) {
Debug.w("", "" + e.getCause());
}
// end whistle detection
} else {
// Debug.e("", "no sound detected");
// no sound detected
if (whistleResultList.getFirst()) {
numWhistles--;
}
whistleResultList.removeFirst();
whistleResultList.add(false);

// MainActivity.whistleValue = numWhistles;
}
// end audio analyst
}

Debug.e("", "Terminating detector thread...");

} catch (Exception e) {
e.printStackTrace();
}
}

private OnWhistleListener onWhistleListener;

public void setOnWhistleListener(OnWhistleListener onWhistleListener) {
this.onWhistleListener = onWhistleListener;
}

public interface OnWhistleListener {
void onWhistle();
}

public int getTotalWhistlesDetected() {
return totalWhistlesDetected;
}
}

RecorderThread.java

public class RecorderThread {

private AudioRecord audioRecord;
private int channelConfiguration;
private int audioEncoding;
private int sampleRate;
private int frameByteSize; // for 1024 fft size (16bit sample size)
byte[] buffer;

public RecorderThread() {
sampleRate = 44100;
frameByteSize = 1024 * 2;

channelConfiguration = AudioFormat.CHANNEL_IN_MONO;
audioEncoding = AudioFormat.ENCODING_PCM_16BIT;

int recBufSize = AudioRecord.getMinBufferSize(sampleRate,
channelConfiguration, audioEncoding); // need to be larger than
// size of a frame
audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,
sampleRate, channelConfiguration, audioEncoding, recBufSize);
buffer = new byte[frameByteSize];
}

public AudioRecord getAudioRecord() {
return audioRecord;
}

public boolean isRecording() {
if (audioRecord.getRecordingState() == AudioRecord.RECORDSTATE_RECORDING) {
return true;
}

return false;
}

public void startRecording() {
try {
audioRecord.startRecording();
} catch (Exception e) {
e.printStackTrace();
}
}

public void stopRecording() {
try {
audioRecord.stop();
} catch (Exception e) {
e.printStackTrace();
}
}

public byte[] getFrameBytes() {
audioRecord.read(buffer, 0, frameByteSize);

// analyze sound
int totalAbsValue = 0;
short sample = 0;
float averageAbsValue = 0.0f;

for (int i = 0; i < frameByteSize; i += 2) {
sample = (short) ((buffer[i]) | buffer[i + 1] << 8);
totalAbsValue += Math.abs(sample);
}
averageAbsValue = totalAbsValue / frameByteSize / 2;

Debug.e("", "averageAbsValue : " + averageAbsValue);

// no input
if (averageAbsValue < 30) {
return null;
}

return buffer;
}

}

用法

   public class DetectionService extends Service implements
OnWhistleListener {

Handler handler;
private DetectorThread detectorThread;
private RecorderThread recorderThread;

@Override
public void onCreate() {
super.onCreate();
handler = new Handler();

}

@Override
public IBinder onBind(Intent intent) {
return null;
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {

try {
if (intent != null && intent.getExtras() != null) {

if (intent.getExtras().containsKey("action")) {
Debug.e("", "action : " + intent.getStringExtra("action"));

if (intent.getStringExtra("action").equals("start")) {
startWhistleDetection();
}

if (intent.getStringExtra("action").equals("stop")) {
stopWhistleDetection();
stopSelf();
}
}
} else {

startWhistleDetection();
Debug.e("", "intent is null OR intent.getExtras() is null");
}
} catch (Exception e) {
e.printStackTrace();
}

return super.onStartCommand(intent, flags, startId);
}

private void startWhistleDetection() {

try {
stopWhistleDetection();
} catch (Exception e) {
e.printStackTrace();
}

recorderThread = new RecorderThread();
recorderThread.startRecording();
detectorThread = new DetectorThread(recorderThread);
detectorThread.setOnWhistleListener(this);
detectorThread.start();

}

private void stopWhistleDetection() {
if (detectorThread != null) {
detectorThread.stopDetection();
detectorThread.setOnWhistleListener(null);
detectorThread = null;
}

if (recorderThread != null) {
recorderThread.stopRecording();
recorderThread = null;
}

}

@Override
public void onDestroy() {
super.onDestroy();
}

@Override
public void onWhistle() {
Debug.e("", "onWhistle()");
}

它会第一时间检测到哨声,直到您不停止服务。但是在停止并再次启动后它没有检测到(不调用监听器)。我只是没能追踪到,可能是什么问题?

录音有问题吗?

最佳答案

我投入了 6 个小时,:D 令人难以置信,录音机在停止时没有释放。停止后我才释放录音机。

源代码有一些愚蠢的小错误。它不是释放记录器。

public void stopRecording() {
try {
audioRecord.stop();
audioRecord.release();

} catch (Exception e) {
e.printStackTrace();
}
}

关于android - 在android中检测 'WhiSTLe'声音,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14767476/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com