2010-12-13 22 views
8

Ho bisogno di eseguire due istanze di AudioTrack allo stesso tempo. Devono essere eseguiti separatamente perché li sto riproducendo a frequenze di campionamento diverse e variabili. Ho scoperto che se li eseguo nello stesso thread, "si alternano". Li sto eseguendo ognuno nel loro thread, ma l'audio sta balbettando.Android: miscelazione di più istanze AudioTrack?

Qualche idea su come realizzare due istanze è piacevole? In caso contrario, qualche consiglio su come mixare due buffer brevi in ​​uno, anche se voglio riprodurli a frequenze di campionamento diverse.

risposta

11

Ho 4 tracce audio in esecuzione e sembrano giocare bene. Test su HTC Desire 1.1ghz OC. Tuttavia a volte mi capita di avere problemi con la discussione. Occasionalmente se tutti e quattro sono in riproduzione, uno non si fermerà quando cerco di unirmi al thread. Devi fare più test. Qui è la mia classe per la riproduzione di un file WAV registrata in un determinato percorso

package com.ron.audio.functions; 

import java.io.BufferedInputStream; 
import java.io.DataInputStream; 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.InputStream; 

import android.media.AudioFormat; 
import android.media.AudioManager; 
import android.media.AudioTrack; 

public class AudioPlayManager implements Runnable { 

private File fileName; 
private volatile boolean playing; 

public AudioPlayManager() { 
    super(); 
    setPlaying(false); 
} 

public void run(){ 
     // Get the length of the audio stored in the file (16 bit so 2 bytes per short) 
     // and create a short array to store the recorded audio. 
     int musicLength = (int)(fileName.length()/2); 
     short[] music = new short[musicLength]; 

     try { 
     // Create a DataInputStream to read the audio data back from the saved file. 
     InputStream is = new FileInputStream(fileName); 
     BufferedInputStream bis = new BufferedInputStream(is); 
     DataInputStream dis = new DataInputStream(bis); 

     // Read the file into the music array. 
     int i = 0; 
     while (dis.available() > 0) { 
      music[i] = dis.readShort(); 
      i++; 
     } 

     // Close the input streams. 
     dis.close();  

     // Create a new AudioTrack object using the same parameters as the AudioRecord 
     // object used to create the file. 
     AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 
               11025, 
               AudioFormat.CHANNEL_CONFIGURATION_MONO, 
               AudioFormat.ENCODING_PCM_16BIT, 
               musicLength, 
               AudioTrack.MODE_STREAM); 
     // Start playback 
     audioTrack.play(); 

     // Write the music buffer to the AudioTrack object 
     while(playing){ 
      audioTrack.write(music, 0, musicLength); 
     } 

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

} 


public void setFileName(File fileName) { 
    this.fileName = fileName; 
} 

public File getFileName() { 
    return fileName; 
} 

public void setPlaying(boolean playing) { 
    this.playing = playing; 
} 

public boolean isPlaying() { 
    return playing; 
} 

}

+0

Grazie! Ci proveremo. Non sto creando il mio AudioTrack nel callback del thread come sei. Immagino che sia la cura (il resto del codice è quasi identico a quello che ho). Questo spiegherebbe perché i due "toggle" di AudioTrack si bloccano a vicenda. – BTR

+0

Fammi sapere se questo funziona per te. Ho anche tutto questo avvolto in un'altra classe che farà tutta la gestione dei thread per me. Posso quindi chiamare il gestore thread e non preoccuparmi del threading per la registrazione o la riproduzione dei flussi. – DeliveryNinja

+2

C'era un po 'di più, ma la vera chiave stava creando AudioTrack all'interno del thread. Avevo un tipo separato di classe "Device" in modo da poter controllare tempo, volume, ecc. Combinandolo nella classe che legge il file e facendo tutto in un solo thread, è possibile giocare in modo piacevole. Ora sto ascoltando brani sul mio Optimus (600mHz). :) – BTR