私がやろうとしていること: Android マイクから音声を (録音せずに) 読み取り、サービスを使用して音声の音量をある程度測定するプログラムを作成しようとしています。今のところ、アクティビティからサービスにパルスを送信して、音をすばやく読み取って、ボリュームメーターとして振幅の Logcat プリントアウトを確認しています。
私の問題: AudioRecord の read メソッドが 0 を返します。
私が試したこと: NullOutputStream を使用する代わりに完全なオーディオを録音しても違いはありません。以前のバージョンのいくつかは、logcat 呼び出しなどの些細な変更が追加された後にランダムに動作し始め、後で動作を停止しました。
私の考え: マイクが別のアプリケーションによって使用されている可能性があると最初は考えていましたが、これが実行されている唯一の注目すべきサービスであっても 0 を返します。
私のサービス:
import org.apache.commons.io.output.NullOutputStream;
public class RecordingService extends Service {
public static final int SAMPLE_RATE = 16000;
private AudioRecord mRecorder;
private File mRecording;
private short[] mBuffer;
public static final NullOutputStream NULL_OUTPUT_STREAM = new NullOutputStream();
public double amplitude = 0.0;
public String TAG = "TAG";
public void onCreate() {
super.onCreate();
}
public int onStartCommand(Intent intent, int flags, int startId){
initRecorder();
mRecorder.startRecording();
mRecording = getFile("raw");
startBufferedWrite(mRecording, intent);
mRecorder.stop();
mRecorder.release();
stopSelf();
return START_STICKY;
}
private void initRecorder() {
int bufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE, AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT);
mBuffer = new short[bufferSize];
mRecorder = new AudioRecord(MediaRecorder.AudioSource.MIC, SAMPLE_RATE, AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT, bufferSize);
}
private void startBufferedWrite(final File file, Intent intent) {
Log.i(TAG, "WRITING");
new Thread(new Runnable() {
@Override
public void run() {
DataOutputStream output = null;
Log.i(TAG, "running");
try {
output = new DataOutputStream(NULL_OUTPUT_STREAM);
Log.i(TAG, "outputset");
double sum = 0;
//problems!
Log.i(TAG, "mBufferlength= " + mBuffer.length);
int readSize = mRecorder.read(mBuffer, 0, mBuffer.length);
Log.i(TAG, "readSize1= " + readSize);
Log.i(TAG, mBuffer.toString());
//problems!
Log.i(TAG, "read");
for (int i = 0; i < readSize; i++) {
output.writeShort(mBuffer[i]);
sum += mBuffer[i] * mBuffer[i];
}
Log.i(TAG, "summed up");
if (readSize > 0) {
Log.i(TAG, "readSize2= "+readSize);
Log.i(TAG, "setting progress");
amplitude = sum / readSize;
Log.i(TAG, "amplitude= " + amplitude);
Log.i(TAG, "sqrt= " + Math.sqrt(amplitude));
}
else {
Log.i(TAG, "readsize <= 0");
}
} catch (IOException e) {
Log.e(TAG, e.getMessage());
} finally {
if (output != null) {
try {
output.flush();
} catch (IOException e) {
Log.e(TAG, e.getMessage());
} finally {
try {
output.close();
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
}
}
}
}
}).start();
}
private File getFile(final String suffix) {
Time time = new Time();
time.setToNow();
return new File(Environment.getExternalStorageDirectory(), time.format("%Y%m%d%H%M%S") + "." + suffix);
}
public void onDestroy() {
super.onDestroy();
}
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
}
私の活動:
public class RecordingActivity extends Activity {
private final String startRecordingLabel = "Start recording";
public String TAG = "TAG";
@Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final Button button = (Button) findViewById(R.id.button);
button.setText(startRecordingLabel);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(final View v) {
Intent intent = new Intent(RecordingActivity.this, RecordingService.class);
Toast.makeText(RecordingActivity.this, "started", Toast.LENGTH_SHORT).show();
RecordingActivity.this.startService(intent);
}
});
}
@Override
public void onDestroy() {
super.onDestroy();
}
}
初めての投稿ですが、分かりやすいと思います。ありがとうございました!