[JAVA] Comprendre les bases de l'enregistrement audio Android

J'ai utilisé la classe AudioRecord pour faire du traitement audio sur Android. C'est un peu un auteur-compositeur, et j'ai fait référence à certaines pages japonaises, mais j'ai peur qu'il y ait beaucoup de parties vagues dans les spécifications ...

Cela peut être difficile à comprendre sans une connaissance de base du traitement de la voix en premier lieu, mais il existe de nombreuses API telles que positionNotificationPeriod '' et notificationMarkerPosition '' que vous ne comprenez pas ce qui est différent.

Donc, je vais laisser une note (code avec commentaires) du document officiel et des spécifications étudiées dans le test local.

AudioRecordSample.kt



import android.media.AudioFormat
import android.media.AudioRecord
import android.media.MediaRecorder
import android.util.Log
import kotlin.math.max

/**
 *Exemple de code pour la classe AudioRecord
 */
class AudioRecordSample {

    //Taux d'échantillonnage(Hz)
    //La garantie de prise en charge de tous les appareils est uniquement 44100
    private val samplingRate = 44100

    //fréquence d'images(fps)
    //Combien de fois vous souhaitez traiter des données audio par seconde
    //Décidez vous-même
    private val frameRate = 10

    //1 trame de données audio(=Valeur courte)Nombre de
    private val oneFrameDataCount = samplingRate / frameRate

    //Nombre d'octets de données audio dans une trame(byte)
    // Byte = 8 bit, Short =Parce que c'est 16 bits,Double court
    private val oneFrameSizeInByte = oneFrameDataCount * 2

    //Taille du tampon de données audio(byte)
    //Exigence 1:Doit être plus grand que oneFrameSizeInByte
    //Exigence 2:Doit être supérieur au minimum requis par l'appareil
    private val audioBufferSizeInByte =
            max(oneFrameSizeInByte * 10, //Fournit un tampon pour 10 images
                    android.media.AudioRecord.getMinBufferSize(samplingRate,
                            AudioFormat.CHANNEL_IN_MONO,
                            AudioFormat.ENCODING_PCM_16BIT))

    fun startRecording() {

        //Créer une instance
        val audioRecord = AudioRecord(
                MediaRecorder.AudioSource.MIC, //Source audio
                samplingRate, //Taux d'échantillonnage
                AudioFormat.CHANNEL_IN_MONO, //Paramètres de chaîne.MONO et STEREO garantissent la prise en charge de tous les appareils
                AudioFormat.ENCODING_PCM_16BIT, //PCM16 garantit la prise en charge de tous les appareils
                audioBufferSizeInByte) //tampon

        //Combien de données vocales traiter( =Nombre de données dans une trame)
        audioRecord.positionNotificationPeriod = oneFrameDataCount

        //Au moment où le nombre spécifié ici est atteint,La suite onMarkerReached est appelée
        //Cela ne semble-t-il pas nécessaire pour un traitement de streaming normal?
        audioRecord.notificationMarkerPosition = 40000 //Ne pas définir s'il n'est pas utilisé.

        //Array pour stocker les données vocales
        val audioDataArray = ShortArray(oneFrameDataCount)

        //Spécifier le rappel
        audioRecord.setRecordPositionUpdateListener(object : AudioRecord.OnRecordPositionUpdateListener {

            //Traitement pour chaque image
            override fun onPeriodicNotification(recorder: AudioRecord) {
                recorder.read(audioDataArray, 0, oneFrameDataCount) //Lire les données audio
                Log.v("AudioRecord", "onPeriodicNotification size=${audioDataArray.size}")
                //Traitez comme vous le souhaitez
            }

            //Traitement de la synchronisation des marqueurs.
            //Appelé lorsque notificationMarkerPosition est atteint
            override fun onMarkerReached(recorder: AudioRecord) {
                recorder.read(audioDataArray, 0, oneFrameDataCount) //Lire les données audio
                Log.v("AudioRecord", "onMarkerReached size=${audioDataArray.size}")
                //Traitez comme vous le souhaitez
            }
        })

        audioRecord.startRecording()
    }
}

C'est juste basique. Je l'écrirai à nouveau si je peux obtenir des informations plus avancées telles que les performances.

Recommended Posts

Comprendre les bases de l'enregistrement audio Android
À propos des bases du développement Android
Surveillance Docker-expliquant les bases des bases-
[Pour les débutants] Comprendre rapidement les bases de Java 8 lambda
Comprendre le mécanisme de base de log4j2.xml
Les bases de SpringBoot + MyBatis + MySQL
[Challenge CircleCI from 0] Apprenez les bases de CircleCI
Comprendre l'échantillon officiel Coffee of Dagger2
Maintenant, j'ai résumé les bases de RecyclerView
[jour: 5] J'ai résumé les bases de Java
Retour sur les bases de Java
Qu'est-ce que JSP? ~ Connaissons les bases de JSP !! ~
[Ruby] Résumé des définitions de classe. Maîtrisez les bases.
[Android] [Java] Gérer l'état de CheckBox de ListView
J'ai compris les bases de la saisie de caractères
Les bases de jQuery que même les freeters peuvent comprendre
L'histoire du réglage de l'application Android avec libGDX
Bases de Ruby
Lisez la documentation officielle de Dagger2 pour comprendre les bases
[Pour les débutants] DI ~ Les bases de DI et DI au printemps ~
J'étais accro au record du modèle associé
J'ai vu la liste du développement Android collectivement
Comprendre les caractéristiques de Scala en 5 minutes (Introduction à Scala)
<Android> Changer la couleur d'arrière-plan de la ligne Liste de ListView
[Android] Comment obtenir la langue de réglage du terminal
J'ai résumé les types et les bases des exceptions Java
[Ruby] Imbrication de classes, héritage et principes de base de soi
Un record d'étude du Spring Framework à partir de zéro
[Android] Accrochez le robinet du lien d'ancrage dans WebViewClient
Le monde de Clara-Rules (2)
Jugement du calendrier
Le monde de Clara-Rules (4)
Le monde de Clara-Rules (1)
Comprenons la fonction!
Le monde de Clara-Rules (3)
Principes de base de l'instruction try-with-resources
Le monde de Clara-Rules (5)
L'idée du tri rapide
Définition des constantes Android
L'idée de jQuery
Je n'ai pas vraiment compris le comportement de Java Scanner et .nextLine ()
À propos de la troncature de String par le nombre d'octets sur Android
J'ai essayé de résumer les bases de kotlin et java
[Android] Quittez l'activité de la source de transition au moment de la transition d'écran
Une histoire remplie des bases de Spring Boot (résolu)
Suivre le mémorandum d'association de fonction (comprendre la description du modèle utilisateur)
[Résumé des livres techniques] Résumé de la lecture "Apprendre Docker à partir des bases"