web-dev-qa-db-fra.com

Comment écrire des octets bruts sur un périphérique audio?

Autrefois, vous pouviez ouvrir /dev/dsp en lecture et en écriture. Désormais, avec PulseAudio, cela ne fonctionne plus.

Je pensais que vous pouviez le faire avec padsp, mais ce code ne s'exécute pas:

import ossaudiodev

f = ossaudiodev.open("w")
fmt, channels, rate = dsp.setparameters(fmt, channels, rate)

(l'exécutant via padsp python script.py)

L'erreur que je reçois est No such file or directory: '/dev/dsp'.

Qu'est-ce que je rate? Comment lire et écrire des octets bruts depuis et vers un périphérique audio, et comment sélectionner celui que je veux utiliser?

5
Stefano Palazzo

Ce script est une fine enveloppe autour de l'API simple de PulseAudio. Il vous permet d’écrire des échantillons sur la sortie par défaut:

#!/usr/bin/env python3

import random
import ctypes
import struct

class NoiseMaker (object):

    PA_SAMPLE_U8 = 0
    PA_STREAM_PLAYBACK = 1

    def __init__(self, rate, channels):
        pat_sample_spec = ctypes.c_buffer(struct.pack("LLB",
            self.PA_SAMPLE_U8, rate, channels))
        self.pa = ctypes.cdll.LoadLibrary("libpulse-simple.so.0")
        self.s = self.pa.pa_simple_new(0, "App", self.PA_STREAM_PLAYBACK,
            0, "App Noise", ctypes.byref(pat_sample_spec), 0, 0,0)

    def write(self, data):
        self.pa.pa_simple_write(self.s, data, len(data), 0)

    def __del__(self):
        self.pa.pa_simple_free(self.s)


one_second_noise = bytes(random.randint(0, 255) for i in range(44100*2))
NoiseMaker(44100, 2).write(one_second_noise)

Le taux (44100) définit le nombre d'échantillons en une seconde de temps réel. Il attend des octets compris entre 0 et 255, ce qui est défini par PA_SAMPLE_U8 (équivalent à 'Unsigned 8-Bit', comme indiqué par Audacity, par exemple). Si vous avez plus d'un canal, des échantillons alternés sont attendus pour chacun d'eux. Ainsi, une seconde de bruit a 44100 échantillons par canal = 88200 échantillons, ceux (modulo 2 = 0) correspondant au canal gauche.

Veuillez noter que ce script ne fonctionne que sur Python 3

5
Stefano Palazzo