Un tampon FIFO est une structure de données couramment nécessaire pour de nombreux cas d'utilisation. Les éléments sont placés dans la mémoire tampon et récupérés dans l'ordre dans lequel ils ont été placés. Il s'agit d'une fonctionnalité similaire à celle d'une file d'attente. La différence entre une file d'attente et un tampon est que dans le tampon, les données insérées sont toutes du même type de données. En outre, une quantité arbitraire de données peut être insérée et la quantité récupérée est également arbitraire.
Quels sont les cas d'utilisation dans lesquels vous souhaitez placer et récupérer des éléments numériques arbitraires du même type ? Plonger dans des domaines autres que le traitement des données : pensez aux comptes bancaires : l'argent est mis en montant différent et retiré en quantités selon les besoins. La même chose s'applique au stockage des céréales dans une ferme. Mais ce sont les banques et les greniers qui le font. Ce qui nous reste en informatique, ce sont les données audio, qui arrivent très rapidement, mais doivent repartir à une vitesse spécifique plus lente pour pouvoir être entendues. Les coupables d'aujourd'hui sont les moteurs de synthèse vocale qui facilitent la communication interactive entre la machine et l'homme. La machine obtient du texte (probablement à partir d'un moteur d'IA) qu'elle convertit en octets audio pour être envoyé à l'humain à une vitesse spécifique que l'humain peut entendre. Comme prévu, la machine génère des octets audio à un rythme rapide qui doivent ensuite être mis en mémoire tampon afin de pouvoir maintenir la transmission à l'humain à un rythme beaucoup plus lent. Une analogie est votre station-service locale. Le texte-parole est le camion-citerne qui pompe beaucoup d'essence à un rythme rapide, remplissant les réservoirs d'essence dans les entrailles de la station-service. Ceux-ci sont ensuite livrés à un rythme beaucoup plus lent dans les voitures ou autres véhicules du client.
En résumé, la conversion du texte en parole (audio) peut s'effectuer beaucoup plus rapidement. Il est nécessaire d'avoir un tampon audio qui reçoit l'audio de la synthèse vocale (tts) pour remplir le tampon. Ce tampon est ensuite vidé au rythme de la parole humaine et est compréhensible par l'humain.
Données audio : les données sont constituées d'une séquence de nombres représentant les valeurs d'un signal audio à intervalles réguliers (appelé taux d'échantillonnage). Il existe également le concept de canaux, qui correspond à plusieurs signaux audio, ce qui aboutit à une séquence de plusieurs valeurs.
Pour les besoins de cet article, nous ne considérerons qu’un seul canal côté entrée et un seul canal côté sortie.
Les exigences sont les suivantes : pouvoir saisir un nombre arbitraire de trames de données audio (une trame est un nombre représentant un point de données audio), qui est un tableau ordonné de valeurs de signaux audio. Du côté de la sortie, être capable de récupérer une quantité arbitraire de ces images. Nous devons bien sûr ajouter des fonctionnalités pratiques pour gérer les limitations, qui sont une taille de tampon limitée (ce qui provoque des conditions de tampon plein à l'entrée), aucune donnée audio disponible (tampon vide du côté de la sortie). D'autres fonctionnalités pratiques incluront le remplissage à zéro des données audio, dans le cas où plus de données audio sont demandées que celles disponibles dans la récupération du tampon.
Ce qui suit décrit une implémentation d'un tel tampon en Python :
Les octets audio entrants sont stockés dans Buffer. Le tampon a un pointeur « inférieur », qui indique dans quelle mesure le tampon est rempli. Il dispose également d'un « pointeur de départ » qui est le début du tampon où les nouvelles données peuvent être poussées. Le pointeur de début est fixé au début du tampon. Le pointeur du bas est « dynamique » et va « de haut en bas » : vers le haut lorsque les données sont extraites et « vers le bas » lorsque les données sont insérées. Les données sont toujours insérées en haut (pointeur de début) du tampon, ce qui entraîne le déplacement des données existantes dans le tampon vers le bas, augmentant ainsi la valeur du pointeur du bas.
La condition de tampon vide se produit lorsque le pointeur inférieur est égal au pointeur de début. La condition de tampon plein se produit lorsque le pointeur inférieur est égal à la longueur du tampon.
Nous pouvons également inclure des « échecs progressifs » pour gérer les conditions dans lesquelles le tampon est plein.
Lorsque le tampon est plein et que des données doivent être insérées, déclenchez une exception. Lorsque le tampon est vide (y compris dans le cas où plus de données sont demandées que ce qui est disponible dans le tampon), renvoie des « zéros » pour les données manquantes. C'est l'équivalent audio du « silence » lorsqu'aucun mot n'est prononcé.
Un schéma de ce tampon est :
Codage : (Avertissement : aucune IA n'a été utilisée pour générer le code ci-dessous. Tout blâme (la louange est meilleure) doit être attribué à l'auteur.)
Suivant les principes orientés objet, le code est écrit sous forme de classe/objet et est facile à utiliser. Le code complet est :
import numpy as np #numpy is the standard package or numerical array processing class AudioBuf: def __init__(self,bufSize:int,name:str='',dtype=np.int16): self.buffer = np.zeros((bufSize), dtype=dtype) self.bufSize=bufSize self.dtype=dtype self.idx=0 self.name=name #give a name to the buffer. def putInBuf(self,inData:np.ndarray[np.dtype[np.int16]]): inData=inData[:, 0] #Get the 1st col = channel 0 - mono remainder = self.bufSize - self.idx #space available for insertion if remainder < len(inData): msg=f'Error: Buffer {self.name} is full' print(msg) self.showBuf() raise ValueError(msg) self.buffer[self.idx:self.idx + len(inData)] = inData self.idx += len(inData) def getFromBuf(self,outDataLen:int = None)->np.ndarray: if not outDataLen: outDataLen=self.idx # return entire data of length is not specified if self.idx >= outDataLen: retVal = self.buffer[:outDataLen] self.buffer[0:self.idx-outDataLen]=self.buffer[outDataLen:self.idx] #move buffer up self.idx -= outDataLen else: retVal=np.zeros((outDataLen), dtype=self.dtype) retVal[0:self.idx] = self.buffer[0:self.idx] self.idx=0 return np.reshape(retVal,(-1,1)) #The -1 value automatically calculates to the number of elements def showBuf(self): print(f'AudioBuf : {self.name} has length= {self.idx} with capacity {self.bufSize}')
La mise en mémoire tampon audio est essentielle et plus importante désormais en raison des nombreuses applications de traitement audio. L'algorithme de tampon audio présenté ci-dessus est une classe Python pratique.