Android - Come aggiungere il mio codec audio a Audiorecord?
Domanda
Attualmente ho un programma Loop Back per testare l'audio sui dispositivi Android.
Utilizza Audiorecord e AudioTrack per registrare l'audio PCM dal microfono e riprodurre l'audio PCM fuori dall'auricolare.
Ecco il codice:
public class Record extends Thread
{
static final int bufferSize = 200000;
final short[] buffer = new short[bufferSize];
short[] readBuffer = new short[bufferSize];
public void run() {
isRecording = true;
android.os.Process.setThreadPriority
(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
int buffersize = AudioRecord.getMinBufferSize(11025,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT);
arec = new AudioRecord(MediaRecorder.AudioSource.MIC,
11025,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT,
buffersize);
atrack = new AudioTrack(AudioManager.STREAM_VOICE_CALL,
11025,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT,
buffersize,
AudioTrack.MODE_STREAM);
atrack.setPlaybackRate(11025);
byte[] buffer = new byte[buffersize];
arec.startRecording();
atrack.play();
while(isRecording) {
arec.read(buffer, 0, buffersize);
atrack.write(buffer, 0, buffer.length);
}
}
}
Come puoi vedere nella creazione di AudioTrack e Auiorecord, la codifica viene fornita tramite l'audioformato, ma ciò consente solo PCM a 16 o 8 bit.
Ora ho la mia implementazione del codec G711 e voglio essere in grado di codificare l'audio dal micro ENCODE (corto lin [], int offset, byte enc [], int frame) e decode (byte enc [], corto lin [], int frame) Metodi ma non sono sicuro di come usarli per codificare e decodificare l'audio da Auiorecord e AudioTrack.
Qualcuno può aiutarmi o indicarmi nella giusta direzione?
Soluzione
Cambia il tuo arec.read(buffer, 0, buffersize)
Chiama per usare il file Bytebuffer
read()
metodo da AudioRecord
.
Una volta che hai i tuoi byte nel ByteBuffer
oggetto, quindi puoi semplicemente inserire la tua chiamata di implementazione G711 di ENCODE e utilizzare il ByteBuffer.asShortBuffer()
Metodo per inserire i dati PCM acquisiti nell'encoder.
Ciò risolverebbe la tua domanda iniziale senza dover introdurre una biblioteca di terze parti per fare quel lavoro per te. (Questa risposta è per le persone future che si imbattono nella domanda).
La mia domanda è perché?
Nel tuo codice sopra si acquisisce i dati PCM dal microfono e li scrivi direttamente al buffer per la riproduzione.
Non ha alcun senso nell'implementazione seguire il percorso di PCM -> G711 (ENCODE) -> G711 (decodifica) -> PCM. Tutto quello che stai facendo è introdurre elaborazioni e latenza non necessarie. Ora, se avessi intenzione di scrivere dati codificati su un file invece di provare a riprodurli attraverso l'orecchio che sarebbe una storia diversa, ma il tuo codice attuale non sembra davvero utile per codificare i dati PCM.
L'introduzione del tuo codec qui avrebbe senso solo nel contesto di scrivere i dati vocali compressi in un file (registrazione dei dati delle chiamate ad esempio in modo compresso) o di inviarli sulla rete o qualcosa del genere.
Altri suggerimenti
Mi rendo conto che questo è un post piuttosto vecchio. Sei stato in grado di far funzionare il tuo G711? Il mio pensiero iniziale sarebbe quello di usare una lib compilata per il kernel e usare JNI per chiamarlo.