Y avait-il une vie avant un CD audio? Décodeur logiciel PCM

Dans le dernier article, nous avons parlé des codes QR dynamiques qui ont été enregistrés sur des cassettes VHS. L'épidémie de PCM m'a également attrapé, il est donc temps de choisir ce format.

Capture avec un processeur PCM

Dans un premier temps, nous allons essayer d'implémenter un décodeur logiciel. Ce n'est pas le dernier article sur ce sujet, car aux enchères japonaises, les processeurs peuvent se terminer et PCM devrait être dans chaque maison! Trouver un lecteur vidéo n'est pas un problème.

Pour travailler, vous avez besoin d'un fichier avec l'enregistrement de ces mêmes QR codes. Vous pouvez l'obtenir en utilisant la carte de capture vidéo. Eh bien, la source du signal, bien sûr. Vous pouvez capturer directement la sortie du processeur ou enregistrer sur un magnétophone. Idéalement, travaillez immédiatement avec le périphérique de capture pour décoder le signal en temps réel.

N'importe quelle langue fera l'affaire. J'ai commencé avec Python. Mais cela s'est avéré plutôt lent sur mon ordinateur portable, donc je suis passé au C ++. Soit dit en passant, indépendamment les uns des autres (presque) notre petite communauté développe 3 projets de décodeur: sur OpenCV (C ++), sur Qt (C ++) et sur LabView. Le premier sera discuté. OpenCV a été choisi en raison de la simplicité de travailler avec des appareils de capture et des vidéos préenregistrées. De plus, toutes les manipulations avec l'image y sont hautement optimisées.

Le premier problème que vous rencontrerez est la perte de données. En tout état de cause, ils seront et ne pourront être évités en aucune manière sans un équipement «spécialisé». PCM utilise plus de lignes que ne le permet la zone visible du cadre. Dans le cas de la région NTSC, ce nombre est de 492 lignes par image avec une zone visible de 480. Dans le cas de PAL, tout est beaucoup plus triste.
1. PCM NTSC 44,056 kHz, PAL 44,1 kHz.
2. VHS . ( ). , . , . , . .
Il y a deux solutions pour ce problème. Travaillez avec la carte de capture d'une manière délicate en contournant le pilote et prenez les données de l'ADC, après quoi elles peuvent être converties en une trame PCM complète, ou marteler sur les lignes manquantes. La deuxième option semble un peu sauvage, mais le format de stockage des données vous permet de récupérer une partie des données. Dans le cas de la région NTSC, il s'avère répondre aux limites du système de correction d'erreur.

En raison de l'utilisation de lignes de service, vous ne pouvez pas prendre une carte vidéo avec une sortie composite et faire jouer le processeur PCM. Iron ignorera tout le cadre s'il ne trouve pas le titre dans une ligne spécifique. Il y a quelques réflexions à ce sujet, mais à ce sujet plus tard.

Pour commencer, le signal vidéo est entrelacé. Chaque trame contient pour ainsi dire deux, composées de lignes paires et impaires. Ils sont appelés champs. C'est avec les champs que fonctionne le processeur PCM. Par conséquent, nous devons également diviser le flux d'origine. Juste avant cela, il serait intéressant de convertir une image en noir et blanc (nuances de gris) en binaire afin de faciliter le travail.

À ce stade, nous rencontrons trois difficultés associées aux fonctionnalités des appareils de capture vidéo. Vous ne pouvez pas utiliser un seuil statique pour binariser une image. Mais OpenCV lui-même résout ce problème, avec l'aide duquel nous obtenons un résultat assez décent avec une ligne magique.

threshold(greyFrame, fullFrame, 0, 255, THRESH_BINARY + THRESH_OTSU);

Le deuxième problème est, tout à coup, la couleur. Les processeurs PCM n'utilisent pas la composante couleur du signal vidéo, mais les cartes de capture peuvent essayer de l'extraire du bruit. Cela est particulièrement visible sur l'EasyCAP le moins cher. Cela peut gâcher un peu le résultat de la binarisation, vous devez donc d'abord convertir l'image en nuances de gris.

cvtColor(srcFrame, greyFrame, CV_BGR2GRAY);

En plus de ce qui précède, EasyCAP parvient à confondre les champs par endroits. Plus précisément, il saute la première ligne, car toutes les autres lignes ne sont pas en place. Pour enregistrer une matinée de maternelle, ce n'est pas très important, mais ici ça devient déjà un problème. Organiser les lignes dans le bon ordre est assez simple. À la fin de chaque trame, il y a une zone sans données. Si nous déplaçons les lignes contenant le signal utile vers le bas, alors les champs sont garantis de revenir à leur place. Lors de mes études, j'ai essayé d'utiliser trois appareils de capture de différentes gammes de prix, mais le plus utile s'est finalement avéré être le moins cher, car cela a révélé un certain nombre de problèmes.

Capture EasyCAP à partir d'une cassette vidéo

Des taches de couleur et un niveau plus élevé de luminosité des bits de données peuvent être observés dans l'image par rapport à la première illustration d'un article capturé sur le Magewell Pro Capture AIO.

Il est temps de se rappeler sur quoi le signal est stocké. Les magnétophones VHS ne diffèrent pas par leur qualité spéciale, car il s'agit d'un format domestique. Les impulsions de synchronisation de trame et de ligne seules ne suffisent pas pour un fonctionnement stable. Par conséquent, des marques de synchronisation supplémentaires sont ajoutées au signal vidéo. Dans chaque ligne au début, il y a une séquence d'alternance de deux «pixels» blancs et deux noirs, et à la fin de la ligne il y a une petite zone avec une luminosité maximale, qui ajuste l'AGC. Les bits de données eux-mêmes ont une luminosité de 60% du maximum pour 1 et de moins de 20% pour 0. Voici un exemple de la raison pour laquelle ces étiquettes sont nécessaires: inversion de l'image des cassettes au début et à la fin de la trame.

Torsions au début du cadre

Selon les marques de synchronisation, dans chaque ligne il y a une zone de données. Ensuite, vous devez déterminer la largeur de bits (seulement 128 bits par ligne) et réduire la ligne d'image à 16 octets.

Examinons de plus près le format des données. La ligne se compose de 8 blocs de 14 bits chacun, contenant des valeurs pour la sortie vers le DAC (échantillons) et des codes de correction d'erreur, et un bloc avec une somme de contrôle (CRC-16 / CCITT-FALSE). Par des sommes de contrôle, les lignes abandonnées sont déterminées, les données dans lesquelles l'appareil tentera de récupérer. Chaque ligne contient trois échantillons pour les canaux gauche et droit, un bloc de parité P (xor de tous les échantillons) et un mystérieux Q. L'ordre est le suivant: L0, R0, L1, R1, L2, R2, P, Q.Aujourd'hui, la correction Q n'est pas possible nous le ferons, car ce matériel n'est pas encore entièrement compris et la mise en œuvre nécessite un débogage.

Ordre des données en lignes

Si vous utilisez "tel quel", une ligne discontinue signifie la perte de trois échantillons à la fois, ce qui sera visible à l'oreille sur un anneau métallique. Mais dida était plus intelligent et a décidé d'enregistrer des données avec des échelles. Un seul bloc est pris sur une ligne. La suivante est prise avec un léger décalage. La marche de l'escalier prend 16 lignes. Le bloc L0 provient d'une ligne. Bloc R0 avec ligne 17 ... Ainsi, en utilisant le bloc de parité, vous pouvez récupérer les données de 16 lignes perdues d'affilée. Mais seulement s'il y a une erreur à l'intérieur de l'échelle. Le bloc Q vous permet de corriger deux erreurs, ce qui restaure jusqu'à 32 lignes perdues.

image

Prenons un exemple simple. Il y a un fragment d'une trame PCM dans laquelle plusieurs lignes sont interrompues (surlignées en rouge). Les 4 premières échelles sont traitées normalement. Le cinquième capturera la ligne brisée. Le bloc Q est d'abord perdu, mais puisqu'il sert à corriger les erreurs et que les échantillons eux-mêmes ne sont pas endommagés, vous pouvez aller plus loin. Avec la sixième échelle, nous faisons de même. Là encore, il y a des échelles intactes jusqu'à 21. Le bloc P en souffre. Il sert également à restaurer les données. Vous pouvez sauter. Nous allons donc à 37 escaliers, où l'échantillon du canal droit sera endommagé. Pour le restaurer, vous devez effectuer XOR pour le bloc de parité et tous les autres échantillons:

R2=L0R0L1R1L2P


En conséquence, nous obtenons la valeur initiale. S'il y a deux erreurs, une tentative est faite pour restaurer en utilisant le bloc Q. S'il y en a plus, alors il n'y a rien à faire avec cela sauf pour interpoler les valeurs des échantillons battus ou pour les réinitialiser.

Le processus de passage à travers le champ peut être observé sur une petite animation GIF.

image

Et donc nous allons jusqu'à ce que la dernière marche de l'échelle repose contre la fin du champ. Le PCM matériel a un tampon circulaire. Dès que la ligne a été traitée, elle peut être remplie de nouvelles données. Ainsi, la dernière étape saute sans interrompre la lecture.

J'ai choisi un principe de travail légèrement différent. Maintenant, il n'y a plus une telle limite de mémoire, donc le tampon a une taille légèrement plus grande: la hauteur du champ plus la hauteur de l'échelle. Dès que l'échelle atteint la fin de la mémoire tampon, les 111 dernières lignes sont transférées au début, et le remplissage de nouvelles données se fait déjà à partir de 112 lignes. Bien sûr, nous ne devons pas oublier que lorsque nous travaillons avec la carte de capture, nous perdons certaines lignes. Par conséquent, assurez-vous de remplir les lignes manquantes avec des zéros afin de les marquer pour une récupération ultérieure par des erreurs CRC.

PCM était à l'origine 14 bits. Mais au fil du temps, lorsque les enregistreurs vidéo VHS ont amélioré la qualité d'image, les fabricants sont passés à 16 bits, sans oublier la compatibilité descendante.
3. 14- PCM 12 . ( ).
Dans le PCM 16 bits, il n'y a pas de bloc Q du tout, il y a donc une marque spéciale dans le champ intitulé "La correction Q n'est pas possible". Au lieu de cela, 2 bits d'échantillons manquants et P. ont été collectés. Dans ce cas, la hauteur de l'échelle n'est pas de 8 marches, mais seulement de 7, car les bits manquants du bloc sont stockés sur sa propre ligne, et non séparément. Comprendre le fonctionnement d'un PCM 16 bits est assez simple en utilisant l'exemple de la capture d'un méandre avec une fréquence de 100 Hz et une amplitude maximale. Tout se met immédiatement en place.

Comparaison de PCM 14 bits et 16 bits

Il est maintenant temps d'enregistrer le résultat dans un fichier wav. La bibliothèque libsndfile vous y aidera. Bien que ... PCM n'enregistre pas les fichiers, mais les lit immédiatement. Ici, vous vous souvenez d'une chose aussi cool, comme la pipe. Lorsque la sortie d'un programme est entrée dans un autre. Nous spécifions simplement stdout comme destination et redirige le flux vers le programme ffplay.

./ggg -i easycap.avi -o - | ffplay -

Vous pouvez maintenant profiter des gouttes et continuer à déboguer le code pour vous en débarrasser ...

C'est tout pour aujourd'hui. Vous pouvez télécharger la source du décodeur à partir de la page sur GitHub: https://github.com/walhi/pcm . Il y a aussi un générateur. Un jour, je vais le concevoir comme un plugin pour foobar ...

Un travail actif est en cours pour terminer la récupération sur le bloc Q, donc pour un travail plus ou moins correct, vous devrez sauter par-dessus les commits. Mais ce sont des bagatelles. Ceux qui souhaitent jouer peuvent télécharger l'exemple de capture.

All Articles