IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Bibliothèques tierces Python Discussion :

[pyav] [av] AudioFrame.np_ndarray valeurs min et max, quel intervalle, quel type ? [Python 3.X]


Sujet :

Bibliothèques tierces Python

  1. #1
    Membre habitué
    Homme Profil pro
    Vagabong étudiant en annalyse du signal.
    Inscrit en
    Avril 2019
    Messages
    123
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Vagabong étudiant en annalyse du signal.
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2019
    Messages : 123
    Points : 162
    Points
    162
    Par défaut [pyav] [av] AudioFrame.np_ndarray valeurs min et max, quel intervalle, quel type ?
    Bonjour,

    Dans l'exemple simplifié ci dessous:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    with av.open("audio_file.ogg", "r") as container:
        stream = container.streams.audio[0]
        frame = next(container.decode(stream))
        array = frame.to_ndarray() # max et min ?
    - Quelle sont les valeurs min et max possible ?
    - Quels types sont possibles ?

    La doc de cette fonction ne dit rien. Les seuls exemples trouvés sont des exemples de tests non quantitatifs. Je n'ai pas réussi à mettre la main sur le code source github.
    D'après la doc, la fonction to_ndarray accepte des kwargs. Mais lesquels ?

    J'ai lancé le code suivant affin de faire une estimation:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    import os
    import pathlib
    import pprint
    import av
     
    dtypes = {}
    for root, _, files in os.walk("/"):
        for file in files:
            suffix = pathlib.Path(file).suffix.lower()
            if suffix not in {".mp3", ".ogg", ".wav", ".wave", ".flac", ".aac", ".mp4", ".mkv", ".avi"}:
                continue
            try:
                with av.open(os.path.join(root, file), "r") as container:
                    for stream in container.streams.audio:
                        for frame in container.decode(stream):
                            array = frame.to_ndarray()
                            dtype = (array.dtype, suffix)
                            if dtype not in dtypes:
                                dtypes[dtype] = (0, 0)
                            mini, maxi = array.min(), array.max()
                            if mini < dtypes[dtype][0] or maxi > dtypes[dtype][1]:
                                dtypes[dtype] = (min(dtypes[dtype][0], mini), max(dtypes[dtype][1], maxi))
            except av.error.InvalidDataError:
                continue
    pprint.pprint(dtypes)
    Voici le résultat:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    {(dtype('int16'), '.wav'): (-32768, 32513),
     (dtype('float32'), '.mp3'): (-1.333013, 1.415781),
     (dtype('float32'), '.ogg'): (-0.7092452, 0.9921398),
     (dtype('int16'), '.mkv'): (-32768, 32767),
     (dtype('float32'), '.avi'): (-1.8093933, 1.8056028),
     (dtype('float32'), '.mkv'): (-1.6858864, 1.8667902),
     (dtype('float32'), '.mp4'): (-1.1447644, 1.1121304)}
    Si vous en savez plus, ça aidera sûrement du monde (et moi aussi )

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Salut,

    Citation Envoyé par robinechuca Voir le message
    Si vous en savez plus, ça aidera sûrement du monde (et moi aussi )
    Il faut récupérer les sources ou poser la question aux développeurs.
    * edit *
    Les sources sont à priori ici.
    GitHub a un search qui permet de trouver tous les modules qui contiennent to_ndarray et un filtrage visuel donne ce module où on verra que les arguments passés à la méthode sont ignorés.

    => reste à faire un bug report pour expliquer aux développeurs qu'il est idiot de mentionner des arguments à une fonction sans les documenter d'autant qu'elle ne les utilise pas.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Membre habitué
    Homme Profil pro
    Vagabong étudiant en annalyse du signal.
    Inscrit en
    Avril 2019
    Messages
    123
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Vagabong étudiant en annalyse du signal.
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2019
    Messages : 123
    Points : 162
    Points
    162
    Par défaut code source trouvé
    J'ai été très mauvais pour ma recherche de code source, le voici : https://github.com/PyAV-Org/PyAV/blo...udio/frame.pyx
    Au moment d’écrire ce message, le module en est à la version 10.0.0.

    Le code source offre une réponse partielle :
    - L'argument **kwargs est ignoré, il est présent seulement pour avoir une API cohérente avec le reste.
    - Les types possibles sont np.float64, np.float32, np.int16, np.int32 et np.uint8.

    Concernant l'étendue des valeurs, le problème n'est pas résolu.
    Pour les types entier, on peu raisonnablement supposer que l'étendue correspond à la plage maximale que permet l'encodage. Toutes la valeurs sont utilisées.

    Par contre pour le type flottant, par exemple np.float32, la valeur maximale encodable serait 3.4028235e+38. D'après l’expérience du premier message, les valeurs utilisées ne semblent pas prendre toute la plage disponible.
    Est-ce que les valeurs sont censées être entre -1 et 1 et le dépassement s'expliquerait par le bruit d'encodage / quantification / décodage ? Je trouve cette hypothèse assez foireuse .

    Il n'y a pas de foire aux questions mais seulement une section "bug reports". Est-ce le bon endroit pour poser la question directement aux développeurs ?

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Si le type choisi dépend du format, il va (vous) falloir étudier les différents formats pour voir s'il y a des "bornes" techniques.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #5
    Membre habitué
    Homme Profil pro
    Vagabong étudiant en annalyse du signal.
    Inscrit en
    Avril 2019
    Messages
    123
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Vagabong étudiant en annalyse du signal.
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2019
    Messages : 123
    Points : 162
    Points
    162
    Par défaut normalisation cracra
    J'ai effectué un test statistique sur 174987536978 échantillons soit environ 550 heures d'audio.
    Il se trouve que 0.0019 % des échantillons flottants sortent de l'intervalle [-1, 1].
    En visualisant la forme d'onde dans les zones qui dépassent j'ai remarqué 2 choses:
    - Très peu d’échantillons consécutifs dépassent, il y en a souvent 1 tout seul par-ci par là.
    - Plus le fichier est compressé, faible débit binaire, plus il y a de dépassements.

    Bref, j'ai l'impression que l'on ne perd pas beaucoup d'information en tronquant entre -1 et 1.
    Une petite fonction qui normalise les échantillons:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    import av
    import numpy as np
     
    def clip_convert(audio_samples: np.ndarray[numbers.Real]) -> np.ndarray[numbers.Real]:
        """
        ** Converts sound samples into float between -1 and 1. **
     
        Minimizes copying and reallocations.
     
        Examples
        --------
        >>> import numpy as np
        >>> import clip_convert
        >>> clip_convert(np.array([-1.5, -1.0, -.5, .5, 1.0, 1.5], dtype=np.float64))
        array([-1. , -1. , -0.5,  0.5,  1. ,  1. ])
        >>> clip_convert(np.array([-1.5, -1.0, -.5, .5, 1.0, 1.5], dtype=np.float32))
        array([-1. , -1. , -0.5,  0.5,  1. ,  1. ], dtype=float32)
        >>> clip_convert(np.array([-1.5, -1.0, -.5, .5, 1.0, 1.5], dtype=np.float16))
        array([-1. , -1. , -0.5,  0.5,  1. ,  1. ], dtype=float16)
        >>> clip_convert(np.array([-2147483648, -1073741824, 1073741824, 2147483647], dtype=np.int32))
        array([-1. , -0.5,  0.5,  1. ])
        >>> clip_convert(np.array([-32768, -16384, 16384, 32767], dtype=np.int16))
        array([-1.        , -0.49999237,  0.50002289,  1.        ])
        >>> clip_convert(np.array([0, 64, 192, 255], dtype=np.uint8))
        array([-1.        , -0.49803922,  0.50588235,  1.        ])
        >>>
        """
        assert isinstance(audio_samples, np.ndarray), audio_samples.__class__.__name__
        if issubclass(audio_samples.dtype.type, numbers.Integral):
            iinfo = np.iinfo(audio_samples.dtype)
            audio_samples = audio_samples.astype(np.float64)
            audio_samples -= .5*np.float64(iinfo.min + iinfo.max)
            audio_samples /= .5*np.float64(iinfo.max - iinfo.min)
        else:
            np.clip(audio_samples, -1, 1, out=audio_samples)
        return audio_samples
    Est-ce que cela vous parait raisonnable de tronquer ?

  6. #6
    Membre habitué
    Homme Profil pro
    Vagabong étudiant en annalyse du signal.
    Inscrit en
    Avril 2019
    Messages
    123
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Vagabong étudiant en annalyse du signal.
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2019
    Messages : 123
    Points : 162
    Points
    162
    Par défaut Reponse officiel issue du code source ffmpeg.
    J'ai posé la question aux développeurs directement.
    Pour une réponse complète (et en Anglais), tout ce trouve ici: https://github.com/PyAV-Org/PyAV/discussions/1073

    En résumé: Oui les valeurs flottantes sont censé être entre -1 et 1, ce qui excède est au dessus du volume maximum. Donc pas trop de scrupules à tronquer.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 25/12/2009, 12h36
  2. [PPT-2007] Etiquettes : valeur min et max d'un graph seulement
    Par Invité dans le forum Powerpoint
    Réponses: 0
    Dernier message: 08/10/2009, 10h23
  3. [XPATH] Rechercher une valeur entre deux valeurs min et max
    Par icicmoi dans le forum XSL/XSLT/XPATH
    Réponses: 1
    Dernier message: 27/10/2008, 12h12
  4. Trouver valeurs min et max de x et y ?
    Par innova dans le forum Algorithmes et structures de données
    Réponses: 18
    Dernier message: 16/01/2008, 22h37
  5. Affectation de la valeur min et max des axes d'un graphe
    Par marsupilami34 dans le forum Access
    Réponses: 2
    Dernier message: 04/09/2006, 14h55

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo