私はAndroid2.1用にプログラミングしています。次の問題について教えていただけますか?
私は3つのファイルを持っています、そして一般的な目的はバッファごとにオーディオトラックバッファでサウンドを再生することです。私はすべてを試したので、ここでかなり必死になっていますが、スピーカーから音が出ません(Androidの統合メディアプレーヤーはエミュレーターを介して音を再生するのに問題はありません)。
ソースコード:
オーディオトラックを実装するオーディオプレーヤークラス。サウンドが含まれているバッファを受け取ります。
public AudioPlayer(int sampleRate, int channelConfiguration, int audioFormat) throws ProjectException {
minBufferSize = AudioTrack.getMinBufferSize(sampleRate, channelConfiguration, audioFormat);
audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, channelConfiguration,
audioFormat, minBufferSize, AudioTrack.MODE_STREAM);
if(audioTrack == null)
throw new ProjectException("Erreur lors de l'instantiation de AudioTrack");
audioTrack.setStereoVolume((float)1.0, (float)1.0);
}
@Override
public void addToQueue(short[] buffer) {
audioTrack.write(buffer, 0, buffer.length*Short.SIZE);
if(!isPlaying ) {
audioTrack.play();
isPlaying = true;
}
}
バッファを埋めるために使用するモデルクラス。通常はファイルからサウンドをロードしますが、ここではデバッグにシミュレーター(440Hz)を使用します。
バッファサイズは非常に緩く選択されます。通常、最初のバッファサイズは6615、次に4410である必要があります。これも、デバッグ専用です。
public void onTimeChange() {
if(begin) {
//First fill about 300ms
begin = false;
short[][] buffer = new short[channels][numFramesBegin];
//numFramesBegin is for example 10000
//For debugging only buffer[0] is useful
fillSimulatedBuffer(buffer, framesRead);
framesRead += numFramesBegin;
audioPlayer.addToQueue(buffer[0]);
}
else {
try {
short[][] buffer = new short[channels][numFrames];
//Afterwards fill like 200ms
fillSimulatedBuffer(buffer, framesRead);
framesRead += numFrames;
audioPlayer.addToQueue(buffer[0]);
} catch (Exception e) {
e.printStackTrace();
}
}
}
private short simulator(int time, short amplitude) {
//a pure A (frequency=440)
//this is probably wrong due to sampling rate, but 44 and 4400 won't work either
return (short)(amplitude*((short)(Math.sin((double)(simulatorFrequency*time)))));
}
private void fillSimulatedBuffer(short[][] buffer, int offset) {
for(int i = 0; i < buffer[0].length; i++)
buffer[0][i] = simulator(offset + i, amplitude);
}
200ミリ秒ごとにmodel.ontimechange()を呼び出すtimeTaskクラス。
public class ReadMusic extends TimerTask {
private final Model model;
public ReadMusic(Model model) {
this.model = model;
}
@Override
public void run() {
System.out.println("Task run");
model.onTimeChange();
}
}
デバッグが私に示したもの:
- timeTaskは正常に機能し、その役割を果たします。
- バッファ値は一貫しているように見え、バッファサイズはminBufSizeよりも大きくなっています。
- オーディオトラックの再生状態は「再生中」です
- モデル関数で例外は発生しません。
どんなアイデアでも大歓迎です!