Script conversion de fichier binaire vers fichier audio série

par skywodd | | Langue : Python 3 | Licence : GPLv3

Description :

Script Python permettant de transformer un fichier binaire en un fichier audio contenant les données binaires sous forme de trames série TTL.

Code source :

Voir le code source brut | Télécharger musical_serial.py | Télécharger musical_serial.py.zip

"""
Transforme un fichier binaire en un fichier audio contenant les données binaires sous forme de trames série TTL.
"""

import wave
import argparse


# Vitesse de communication série
SERIAL_BAUDRATE = 2400

# Fréquence d'échantillonnage (min 4000 ~ max 48000)
AUDIO_SAMPLE_RATE = 44100


def convert_binary_file(input_filename, output_filename):
    """
    Transforme le fichier binaire fourni en un fichier audio contenant les données binaire du fichier source sous forme de trames série TTL.
    """

    # Ouvre le fichier d'entrée et de sortie
    with open(input_filename, 'rb') as fi:
        with wave.open(output_filename, 'wb') as fo:

            # Configure l'entête du fichier Wave
            fo.setnchannels(1)  # Mono
            fo.setsampwidth(1)  # 8 bits
            fo.setframerate(AUDIO_SAMPLE_RATE)
 
            # Calcul le nombre d'échantillons audio par bit
            # Plus il y a d'échantillons par bit plus la qualité du signal audio sera grande
            # Une fréquence d'échantillonnage élevé donnera donc les meilleurs résultats
            NB_SAMPLES_PER_BIT = AUDIO_SAMPLE_RATE // SERIAL_BAUDRATE

            # Constantes pour la communication série
            BIT_ONE = b'\x00' * NB_SAMPLES_PER_BIT
            BIT_ZERO = b'\xFF' * NB_SAMPLES_PER_BIT
            FRAME_BREAK = BIT_ZERO * 20
            FRAME_IDLE = BIT_ONE * 20
            writeframes = fo.writeframes
            
            # Début du fichier audio
            writeframes(FRAME_BREAK)
            writeframes(FRAME_IDLE)

            # Conversion octet par octet
            for data in fi.read():
                
                # Ajoute un bit de start au buffer audio
                writeframes(BIT_ZERO)
             
                # Ajoute 8 bits de données au buffer audio
                for i in range(0, 8):
                    if data & (1 << i):
                        writeframes(BIT_ONE)
                    else:
                        writeframes(BIT_ZERO)

                # Ajoute un bit de stop au buffer audio
                writeframes(BIT_ONE)

            # Fin du fichier audio
            writeframes(FRAME_IDLE * 10)


# CLI wrapper
if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='Turn binary data into a serial-like signal audio wave file.')
    parser.add_argument('input_filename', metavar='<INPUT FILE>', help='The input binary file.')
    parser.add_argument('output_filename', metavar='<OUTPUT FILE>', help='The output audio wave file.')

    args = parser.parse_args()
    convert_binary_file(args.input_filename, args.output_filename)