简体   繁体   English

通过AudioTrack播放WAV文件多次

[英]Play a WAV File Mulitple Times Through AudioTrack

I am making a metronome app that uses AudioTrack to play different sounds for different instruments. 我正在制作一个使用AudioTrack来为不同乐器播放不同声音的节拍器应用。 I want to use a .wav file that I have of one hit on a cowbell for one of the options. 我想使用一个.wav文件,其中一个选项使我一击而过。 I can get the first cowbell hit to work but then it doesn't play any after that. 我可以击中第一个牛铃,但是此后它再也不会播放。

MainActivity.java MainActivity.java

metronome.playInstrumental(getResources().openRawResource(R.raw.cowbell));

Metronome.java Metronome.java

public Metronome(Handler handler) {
    audioGenerator.createPlayer();
    this.mHandler = handler;
}

public void calcSilence() {
    silence = (int) (((60 / bpm) * 8000) - tick);
    soundTickArray = new double[this.tick];
    soundTockArray = new double[this.tick];
    silenceSoundArray = new double[this.silence];
    double[] tick = audioGenerator.getSineWave(this.tick, 8000, beatSound);
    double[] tock = audioGenerator.getSineWave(this.tick, 8000, electronicSound);
    for(int i = 0; i < this.tick; i++) {
        soundTickArray[i] = tick[i];
        soundTockArray[i] = tock[i];
    }
    for(int i = 0; i < silence; i++)
        silenceSoundArray[i] = 0;
}

public void playInstrumental(InputStream inputStream) {
    calcSilence();
    do {
        msg = new Message();
        msg.obj = ""+currentBeat;

        audioGenerator.playSound(inputStream);
        mHandler.sendMessage(msg);
        audioGenerator.writeSound(silenceSoundArray);
    } while(play);
}

AudioGenerator.java AudioGenerator.java

public class AudioGenerator {

private int sampleRate;
private AudioTrack audioTrack;

public AudioGenerator(int sampleRate) {
    this.sampleRate = sampleRate;
}

public double[] getSineWave(int samples, int sampleRate, double frequencyOfTone){
    double[] sample = new double[samples];
    for (int i = 0; i < samples; i++) {
        sample[i] = Math.sin(2 * Math.PI * i / (sampleRate / frequencyOfTone));
    }
    return sample;
}

public byte[] get16BitPcm(double[] samples) {
    byte[] generatedSound = new byte[2 * samples.length];
    int index = 0;
    for (double sample : samples) {
        // scale to maximum amplitude
        short maxSample = (short) ((sample * Short.MAX_VALUE));
        // in 16 bit wav PCM, first byte is the low order byte
        generatedSound[index++] = (byte) (maxSample & 0x00ff);
        generatedSound[index++] = (byte) ((maxSample & 0xff00) >>> 8);
    }
    return generatedSound;
}

public void createPlayer(){
    audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
            sampleRate, AudioFormat.CHANNEL_OUT_MONO,
            AudioFormat.ENCODING_PCM_16BIT, sampleRate,
            AudioTrack.MODE_STREAM);

    audioTrack.play();
}

public void writeSound(double[] samples) {
    byte[] generatedSnd = get16BitPcm(samples);
    audioTrack.write(generatedSnd, 0, generatedSnd.length);
}

public void destroyAudioTrack() {
    audioTrack.stop();
    audioTrack.release();
}

public void playSound(InputStream inputStream) {
    int i = 0;
    int bufferSize = 512;
    byte [] buffer = new byte[bufferSize];
    try {
        while((i = inputStream.read(buffer)) != -1) {
            audioTrack.write(buffer, 0, i);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }



}

} }

I was able to get it to work using this: 我能够使用它来使其工作:

public void playSound(InputStream inputStream) {
    int bufferSize = 512;
    byte[] buffer = new byte[bufferSize];
    i = 0;
    try {
        while((i = inputStream.read(buffer)) > -1) {
            audioTrack.write(buffer, 0, i);
        }
        inputStream.reset();
    } catch (IOException e) {
        e.printStackTrace();
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM