web-dev-qa-db-fra.com

Taux d'échantillonnage pris en charge par Android AudioRecord

J'essaie de comprendre quelles fréquences d'échantillonnage sont prises en charge pour les téléphones fonctionnant sous Android 2.2 ou version ultérieure. Nous aimerions échantillonner à un taux inférieur à 44,1 kHz sans avoir à ré-échantillonner.
Je sais que tous les téléphones prennent en charge 44100Hz, mais je me demandais s’il existe un tableau indiquant les taux d’échantillonnage valables pour certains téléphones. J'ai vu la documentation d'Android ( http://developer.Android.com/reference/Android/media/AudioRecord.html ) mais cela n'aide pas beaucoup.
Quelqu'un at-il trouvé une liste de ces taux d'échantillonnage?

31
Summit

L'affiche originale a probablement évolué depuis longtemps, mais je la posterai au cas où quelqu'un d'autre trouverait cette question.

Malheureusement, selon mon expérience, chaque appareil peut prendre en charge différentes fréquences d'échantillonnage. Le seul moyen sûr de connaître les fréquences d'échantillonnage prises en charge par un périphérique consiste à les tester individuellement en vérifiant que le résultat de AudioRecord.getMinBufferSize () est non négatif (ce qui signifie qu'une erreur s'est produite) et renvoie une taille de mémoire tampon minimale valide.

public void getValidSampleRates() {
    for (int rate : new int[] {8000, 11025, 16000, 22050, 44100}) {  // add the rates you wish to check against
        int bufferSize = AudioRecord.getMinBufferSize(rate, AudioFormat.CHANNEL_CONFIGURATION_DEFAULT, AudioFormat.ENCODING_PCM_16BIT);
        if (bufferSize > 0) {
            // buffer size is valid, Sample rate supported

        }
    }
}
56
Yahma

Android dispose de la fonction AudioManager.getProperty() pour acquérir la taille minimale de la mémoire tampon et obtenir la fréquence d'échantillonnage préférée pour l'enregistrement et la lecture audio. Mais oui bien sûr, AudioManager.getProperty () n'est pas disponible au niveau de l'API <17 . Voici un exemple de code sur l'utilisation de cette API.

// To get preferred buffer size and sampling rate.
AudioManager audioManager = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
String rate = audioManager.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE);
String size = audioManager.getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER);
Log.d("Buffer Size and sample rate", "Size :" + size + " & Rate: " + rate);

Bien que ce soit une réponse tardive, j'ai pensé que cela pourrait être utile.

14
Reaz Murshed

Malheureusement, même tous les téléphones ne prennent pas en charge le taux supposé de 44,1 kHz :(

J'ai testé un Samsung GalaxyY (GT-S5360L) et si vous enregistrez à partir de la source Camcorder (microphone d'ambiance), les seuls débits pris en charge sont 8kHz et 16kHz. L'enregistrement à 44,1 kHz produit un déchirement absolu et à 11,025 kHz, un enregistrement dont la hauteur est modifiée avec une durée légèrement inférieure à celle du son d'origine.

De plus, les stratégies suggérées par @Yahma et @Tom échouent sur ce téléphone particulier, car il est possible de recevoir une taille de mémoire tampon positive et minimale à partir d'une configuration non prise en charge, et pire encore, j'ai été obligé de réinitialiser le téléphone pour obtenir le la pile audio fonctionne à nouveau, après avoir tenté d'utiliser une classe AudioRecord initialisée à partir de paramètres produisant une instance supposée valide, (sans levée d'exception) AudioTrack ou AudioRecord.

Franchement, je suis un peu inquiet des problèmes que je prévois lorsque je lance une application de son à l'état sauvage. Dans notre cas, nous sommes obligés d'introduire une couche coûteuse de conversion du taux d'échantillonnage si nous nous attendons à réutiliser nos algorithmes (avec un taux d'enregistrement de 44,1 kHz) sur ce modèle de téléphone particulier.

:(

13
user1222021

J'ai un téléphone (Acer Z3) sur lequel AudioRecord.getMinBufferSize (...) affiche une taille de tampon positive lorsque je teste 11025 Hz. Cependant, si je lance par la suite

audioRecord = new AudioRecord(...);
int state = audioRecord.getState();
if (state != AudioRecord.STATE_INITIALIZED) ...

Je peux voir que ce taux d'échantillonnage ne représente en fait pas une configuration valide (comme l'a souligné l'utilisateur1222021 le 5 juin 2012). Ma solution consiste donc à exécuter les deux tests pour trouver un taux d'échantillonnage valide.

3
Jorg K

Cette méthode donne le taux d'échantillonnage minimum audio pris en charge par votre périphérique.

NOTE: Vous pouvez inverser la boucle for pour obtenir le taux d'échantillonnage maximum pris en charge par votre périphérique (n'oubliez pas de changer le nom de la méthode).

NOTE 2 : Bien que le document Android indique que la fréquence d'échantillonnage est prise en charge jusqu'à 48 000 (48 khz), j'ai ajouté toutes les fréquences d'échantillonnage possibles (comme dans wikipedia), car ceux qui savent que de nouveaux périphériques peuvent enregistrer l'audio UHD dans des fréquences de capture (d'échantillonnage) supérieures.

private int getMinSupportedSampleRate() {
    /*
     * Valid Audio Sample rates
     * 
     * @see <a
     * href="http://en.wikipedia.org/wiki/Sampling_%28signal_processing%29"
     * >Wikipedia</a>
     */
    final int validSampleRates[] = new int[] { 8000, 11025, 16000, 22050,
            32000, 37800, 44056, 44100, 47250, 48000, 50000, 50400, 88200,
            96000, 176400, 192000, 352800, 2822400, 5644800 };
    /*
     * Selecting default audio input source for recording since
     * AudioFormat.CHANNEL_CONFIGURATION_DEFAULT is deprecated and selecting
     * default encoding format.
     */
    for (int i = 0; i < validSampleRates.length; i++) {
        int result = AudioRecord.getMinBufferSize(validSampleRates[i],
                AudioFormat.CHANNEL_IN_DEFAULT,
                AudioFormat.ENCODING_DEFAULT);
        if (result != AudioRecord.ERROR
                && result != AudioRecord.ERROR_BAD_VALUE && result > 0) {
            // return the mininum supported audio sample rate
            return validSampleRates[i];
        }
    }
    // If none of the sample rates are supported return -1 handle it in
    // calling method
    return -1;
}
2
Vigneshwaran.m

J'aimerais proposer une alternative à la réponse de Yahma. 

Je suis d'accord avec sa proposition selon laquelle il doit être testé (bien que cela varie probablement en fonction du modèle, pas du périphérique), mais utiliser getMinBufferSize me semble un peu indirect.

Afin de tester si un taux d'échantillonnage souhaité est pris en charge, je suggère d'essayer de construire une instance AudioTrack avec le taux d'échantillonnage souhaité - si le taux d'échantillonnage spécifié n'est pas pris en charge, vous obtiendrez une exception du formulaire:

"Java.lang.IllegalArgumentException: 2756Hz n'est pas une fréquence d'échantillonnage prise en charge"

2
Tom

Juste quelques informations mises à jour ici. J'ai passé un peu de temps à essayer d'accéder à l'enregistrement à partir du microphone pour utiliser Android 6 (4.4 KitKat était bien). L'erreur affichée était identique à celle que j'avais pour 4.4 lorsque j'utilisais des paramètres incorrects pour la fréquence d'échantillonnage/pcm, etc. Mais mon problème était que les autorisations dans AndroidManifest.xml ne suffisent plus pour Il faut maintenant que le temps d'exécution soit écoulé: https://developer.Android.com/training/permissions/requesting.html

0
user5292841
    public  class Bigestnumber extends AsyncTask<String, String, String>{
        ProgressDialog pdLoading = new ProgressDialog(MainActivity.this);

        @Override
        protected String doInBackground(String... params) {
            final int validSampleRates[] = new int[]{
                    5644800, 2822400, 352800, 192000, 176400, 96000,
                    88200, 50400, 50000, 48000,47250, 44100, 44056, 37800, 32000, 22050, 16000, 11025, 4800, 8000};
            TrueMan = new ArrayList <Integer> ();
            for (int smaple : validSampleRates){
                if(validSampleRate(smaple) == true) {
                    TrueMan.add(smaple);
                }}


            return null;
        }
        @Override
        protected void onPostExecute(String result) {

            Integer largest = Collections.max(TrueMan);
            System.out.println("Largest   " + String.valueOf(largest));



        }

    }

   public boolean validSampleRate(int sample_rate) {
        AudioRecord recorder = null;
        try {
            int bufferSize = AudioRecord.getMinBufferSize(sample_rate, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
            recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, sample_rate, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize);
        } catch(IllegalArgumentException e) {
            return false;
        } finally {
            if(recorder != null)
                recorder.release();
        }
        return true;
    }

Ce code vous donnera un taux d'échantillonnage maximum pris en charge sur votre système d'exploitation Android. Déclarez simplement ArrayList <Integer> TrueMan; au début de la classe. Vous pouvez ensuite utiliser une fréquence d'échantillonnage élevée dans AudioTrack et AudioRecord pour obtenir une meilleure qualité sonore. Référence

0
Fatih Şennik