# script audio.py
# (C) Fabrice Sincère ; Jean-Claude Meilland et moi...
# RESTRICTIONS : PCM mono 16 bits signés ( -32 767 -> + 32 767 )

import wave
import struct
import binascii

def open_wav( nom_fichier: str )->list:
    ''' Lecture d'un fichier WAV 16 bits mono
    ENTREE :
        nom_fichier = nom du fichier .WAV à ouvrir
    SORTIES :
        data = tableau des échantillons
        fech = fréquence d'échantillonage ( en Hz )
    '''
    data = [] # tableau des échantillons, vide si fichier pas mono ou pas sur 16 bits
        
    fichier = wave.open( nom_fichier,'rb' ) # ouverture du fichier en lecture
    fech = fichier.getframerate() # fréquence d'échantillonnage
    
    if (fichier.getnchannels() != 1): # test si mono
        print('Le fichier son doit être mono.')

    elif (fichier.getsampwidth() != 2): # test profondeur encodage
        print('Le fichier son doit être encodé sur 16 bits. (Ici: '+str(8*fichier.getsampwidth())+' bits.)')
                
    else :

    # construction du tableau des échantillons
        for i in range( fichier.getnframes() ): # parcours de la suite des échantillons ( getnframes() = nombre total d'échantillons )
        
            valeur = fichier.readframes(1) # lecture d'un échantillon et passage au suivant
            data.append(struct.unpack("=h",valeur)[0]) # formule auto-magique pour le décodage...
                        
    fichier.close()

    return data, fech


def write_wav(nom_fichier: str , data: list , fech: int )-> None :
    ''' écriture d'un fichier WAV 16 bits mono
    ENTREES :
        nom_fichier = nom du fichier .WAV  à écrire
        data = tableau des échantillons entiers sur 16 bits signés ( valeurs comprises entre - 32 767 et + 32 767 )
        fech = fréquence d'échantillonnage ( en Hz ) : 8000, 11025, 22050, 41 000, 44100 et éventuellement 48000 et 96000
    SORTIE :
        aucune
    '''
    fichier = wave.open(nom_fichier,'w')

    # création en-tête
    nbCanal = 1    # mono
    nbOctet = 2    # taille d'un échantillon : 2 octets = 16 bits
    nbEchantillon = len(data) # nombre total d'échantillon

    parametres = (nbCanal,nbOctet,fech,nbEchantillon,'NONE','not compressed')# tuple
    fichier.setparams(parametres)    # création de l'en-tête (44 octets)

    # écriture des données
    print('Veuillez patienter...')
    
    for i in range(nbEchantillon):
        
        data[i] = int(data[i]) # au cas où une valeur non entière traînerait...

        # écrétage si valeur en dehors de l'intervalle [-32767,+32767]
        if ( data[i] < -32767 ):
            data[i] = -32767
        elif ( data[i] > 32767 ): 
            data[i] = 32767 
                   
        fichier.writeframes(wave.struct.pack('h',data[i])) # codage et écriture échantillon 16 bits signés

    print("Écriture fichier WAV: '"+nom_fichier+"' terminée.")

    fichier.close()
