Capture Audio PCM avec Android et Transformation en WAV et MP3

La numériastion de données audio brutes sur Android repose sur l'API AudioRecord. Les flux PCM représentent des signaux numériques non compressés, définis par plusieurs paramètres clés.

Paramètres fondamentaux du PCM :

  • Profondeur de bits (quantification) : influence la plage dynamique de l'enregistrement.
  • Fréquence d'échantillonnage : détermine les fréquences captruables.
  • Nombre de canaux : mono ou stéréo selon la configuration.

Pour estimer la taille d'un fichier PCM (exemple : 44100 Hz, 16 bits, stéréo, 60 secondes) :

Taille = Débit binaire × Durée ÷ 8 = (Profondeur × Fréquence × Canaux × Temps) ÷ 8 ≈ 10,34 Mo

Configuration de l'enregistreur Audio


AudioRecord capturer = new AudioRecord(
    MediaRecorder.AudioSource.MIC,
    44100,
    AudioFormat.CHANNEL_IN_STEREO,
    AudioFormat.ENCODING_PCM_16BIT,
    tailleBuffer
);

La variable tailleBuffer est obtenue via AudioRecord.getMinBufferSize().

Processus de capture en arrière-plan


class ThreadEnregistrement implements Runnable {
    public void run() {
        capturer.startRecording();
        FileOutputStream sortie = null;
        try {
            sortie = new FileOutputStream(cheminFichier);
            byte[] echantillons = new byte[tailleBuffer];
            while (actif) {
                int lu = capturer.read(echantillons, 0, echantillons.length);
                sortie.write(echantillons, 0, lu);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            capturer.stop();
            if (sortie != null) {
                try { sortie.close(); } catch (IOException e) {}
            }
        }
    }
}

Le booléen "actif" permet de contrôler la boucle d'enregistrement.

Interruption de la capture


public void arreterEnregistrement() {
    actif = false;
}

Génération d'un fichier WAV

Le format WAV encapsule des données PCM dans une structure standardisée avec un en-tête de 44 octets. Voici une implémentation pour construire cet en-tête :


private void ajouterEnteteWAV(FileOutputStream sortie, long tailleAudio, int freqEchantillon, int canaux, int bitsParEchantillon) throws IOException {
    byte[] entete = new byte[44];
    long debit = freqEchantillon * canaux * bitsParEchantillon / 8;
    long tailleTotale = tailleAudio + 36;

    // Section RIFF
    entete[0] = 'R'; entete[1] = 'I'; entete[2] = 'F'; entete[3] = 'F';
    entete[4] = (byte)(tailleTotale & 0xFF);
    entete[5] = (byte)((tailleTotale >> 8) & 0xFF);
    entete[6] = (byte)((tailleTotale >> 16) & 0xFF);
    entete[7] = (byte)((tailleTotale >> 24) & 0xFF);

    // Type de fichier WAVE
    entete[8] = 'W'; entete[9] = 'A'; entete[10] = 'V'; entete[11] = 'E';

    // Sous-bloc format PCM
    entete[12] = 'f'; entete[13] = 'm'; entete[14] = 't'; entete[15] = ' ';
    entete[16] = 16; // taille du sous-bloc
    entete[20] = 1;  // format PCM
    entete[22] = (byte)canaux;
    entete[24] = (byte)(freqEchantillon & 0xFF);
    entete[25] = (byte)((freqEchantillon >> 8) & 0xFF);
    entete[26] = (byte)((freqEchantillon >> 16) & 0xFF);
    entete[27] = (byte)((freqEchantillon >> 24) & 0xFF);
    entete[28] = (byte)(debit & 0xFF);
    entete[29] = (byte)((debit >> 8) & 0xFF);
    entete[30] = (byte)((debit >> 16) & 0xFF);
    entete[31] = (byte)((debit >> 24) & 0xFF);
    entete[32] = (byte)(canaux * bitsParEchantillon / 8);
    entete[34] = (byte)bitsParEchantillon;

    // Sous-bloc data
    entete[36] = 'd'; entete[37] = 'a'; entete[38] = 't'; entete[39] = 'a';
    entete[40] = (byte)(tailleAudio & 0xFF);
    entete[41] = (byte)((tailleAudio >> 8) & 0xFF);
    entete[42] = (byte)((tailleAudio >> 16) & 0xFF);
    entete[43] = (byte)((tailleAudio >> 24) & 0xFF);

    sortie.write(entete, 0, 44);
}

Compression vers le format MP3

La conversion PCM vers MP3 exploite la bibliothèque LAME pour appliquer une compression preceptuelle, réduisant la taille du fichier tout en préservant la qualité audible.

Étiquettes: Android AudioRecord PCM WAV MP3

Publié le 9 juin à 10h52