Module de traitement du signal acoustique qui peut être utilisé avec Python-Sounddevice ASIO [Application]

introduction

Cet article est une suite du module de traitement des périphériques audio qui peut être utilisé avec le périphérique Python-Sound ASIO [Basic]. Veuillez consulter ici la méthode de configuration initiale pour utiliser le périphérique audio à partir de la préparation avant de l'utiliser, ainsi que la méthode de lecture de base, la méthode d'enregistrement, la méthode d'enregistrement / lecture simultanée et la méthode de diffusion en continu pour le périphérique audio.

Éléments traités dans cet article

Dans cet article, j'aimerais écrire sur la méthode de mappage des canaux à l'aide d'un périphérique audio (entrée de votre microphone préféré et sortie de votre haut-parleur préféré dans un environnement multicanal).

Voir ici pour plus de détails Officiel du périphérique audio Python

Postscript

Avec la mise à jour, il semble que l'opération soit devenue plus facile. Les articles suivants décrivent les anciennes versions, consultez donc la documentation officielle.

Méthode de base de mappage des canaux

Par exemple, supposons que vous ayez un réseau d'enceintes comme celui-ci スクリーンショット 2019-12-04 17.45.36.png Si vous souhaitez émettre la source sonore de 5 canaux dans l'ordre à partir des haut-parleurs de 5 canaux, il n'y a pas de problème car le côté du périphérique audio attribue automatiquement les canaux.

Si vous souhaitez reproduire la source sonore d'un canal depuis n'importe quel haut-parleur (3e haut-parleur cette fois) 1 canal, procédez comme suit.

MonoChannelPlayback.py


out = [-1,-1,0,-1,-1]
sd.play(..., mapping = out ,...)

Ensuite, si vous souhaitez émettre la source sonore de 3 canaux à partir de n'importe quel haut-parleur (2e, 3e, 5e haut-parleur cette fois) 3 canaux, procédez comme suit.

MultiChannelsPlayback.py


out = [-1,0,1,-1,2]
sd.play(..., mapping = out ,...)

En d'autres termes, si vous faites une liste avec [-1] pour les enceintes que vous ne voulez pas émettre et [0] [1] [2] .. pour les enceintes que vous souhaitez émettre, et les mettez en mappage, elles seront assignées. Aussi,

MultiChannelsPlayback.py


out = [-1,1,0,-1,2]
sd.play(..., mapping = out ,...)

Vous pouvez changer l'ordre des enceintes qui produisent le son.

Paramètres pour chaque API

Cette section décrit la méthode de réglage lors du contrôle des entrées / sorties via des API uniques telles que ASIO, Core Audio et WAS API. Pour vérifier l'API actuellement prise en charge par votre machine [Paramètres initiaux de l'équipement utilisé](https://qiita.com/MikuMaekawa/items/aaac6df5d6cee2f8cf71#%E4%BD%BF%E7%94%A8% E6% A9% 9F% E6% 9D% 90% E3% 81% AE% E8% A8% AD% E5% AE% 9A) ou essayez la commande suivante.

checkAPI.py


sd.query_hostapis(index=None)

Valeur de retour

({'name': 'Core Audio',
  'devices': [0, 1, 2],
  'default_input_device': 0,
  'default_output_device': 1},)

ASIO Cliquez ici pour les paramètres de mappage des canaux dans ASIO. Ceci est contrôlé en supposant qu'il existe un environnement avec 5 canaux pour la sortie du haut-parleur et 2 canaux pour l'entrée du microphone. スクリーンショット 2019-12-05 14.11.48.png

ASIOMultiChannnelsControl.py


out = [0,1,2,3,4]
in = [0,1]

asio_out = sd.AsioSettings(channel_map = out)
asio_in = sd.AsioSettings(channel_map = in)

#Régénération
sd.play(..., extra_settings=asio_out)

#enregistrement
recdata = sd.rec(..., channels=2, extra_settings=asio_in,...)

#Enregistrement et lecture simultanés
recdata = sd.playrec(...,channels=2, extra_settings=(asio_in,asio_out),... )

Vous pouvez également définir extra_setting comme paramètre par défaut si vous savez que vous utiliserez les mêmes paramètres tout le temps.

default_map.py


out = [0,1,2,3,4]
in = [0,1]

asio_out = sd.AsioSettings(channel_map = out)
asio_in = sd.AsioSettings(channel_map = in)

sd.default.extra_settings = (asio_in,asio_out)

Core Audio La méthode est presque la même que chez ASIO

CoreAudioMultiChannnelsControl.py


out = [0,1,2,3,4]
in = [0,1]

ca_out = sd.CoreAudioSettings(channel_map = out)
ca_in = sd.CoreAudioSettings(channel_map = in)

#Régénération
sd.play(..., extra_settings=ca_out)

#enregistrement
recdata = sd.rec(..., channels=2, extra_settings=ca_in,...)

#Enregistrement et lecture simultanés
recdata = sd.playrec(...,channels=2, extra_settings=(ca_in,ca_out),... )

WASAPI La même chose est vraie pour WASAPI

WasapiMultiChannnelsControl.py


out = [0,1,2,3,4]
in = [0,1]

wasapi_out = sd.WasapiSettings(channel_map = out)
wasapi_in = sd.WasapiSettings(channel_map = in)

#Régénération
sd.play(..., extra_settings=wasapi_out)

#enregistrement
recdata = sd.rec(..., channels=2, extra_settings=wasapi_in,...)

#Enregistrement et lecture simultanés
recdata = sd.playrec(...,channels=2, extra_settings=(wasapi_in,wasapi_out),... )

finalement

Ceci conclut l'explication du périphérique sonore. J'espère que le nombre d'utilisateurs de périphériques audio augmentera dans le monde, et j'espère que divers programmes super-pratiques et les plus puissants utilisant des périphériques sonores déborderont dans le monde.

Enfin, je dirai au revoir au programme qui trouve automatiquement la réponse impulsionnelle du réseau de haut-parleurs multicanaux que j'ai utilisé à la tête factice sans passer par le logiciel DAW. Je vous remercie pour votre travail acharné.

Exemple de programme de mesure de réponse impulsionnelle

J'écrirai un article de commentaire quand j'en aurai envie, mais peut-être que les gens qui l'utilisent n'ont pas besoin de commentaire ...

InpulseResponse.py


import numpy as np
import scipy as sp
import sounddevice as sd
import wave
import struct

#Setting
Fs=44100
small=1000000 #Ajustez le volume à 1 / petit car le son du fichier wav préparé était trop fort

#sounddevise Setting
sd.default.samplerate=Fs
print(sd.query_devices())
#Une liste des appareils connectés apparaîtra, alors entrez l'ID de l'appareil.
deviceNo = input("Please enter the ID of the device to use  :" )
sd.default.device = int(deviceNo)

area = 1

#mapping
out1 = sd.CoreAudioSettings(channel_map=[0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1])
out2 = sd.CoreAudioSettings(channel_map=[-1,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1])
out3 = sd.CoreAudioSettings(channel_map=[-1,-1,0,-1,-1,-1,-1,-1,-1,-1,-1,-1])
out4 = sd.CoreAudioSettings(channel_map=[-1,-1,-1,0,-1,-1,-1,-1,-1,-1,-1,-1])
out5 = sd.CoreAudioSettings(channel_map=[-1,-1,-1,-1,0,-1,-1,-1,-1,-1,-1,-1])
out6 = sd.CoreAudioSettings(channel_map=[-1,-1,-1,-1,-1,0,-1,-1,-1,-1,-1,-1])
out7 = sd.CoreAudioSettings(channel_map=[-1,-1,-1,-1,-1,-1,0,-1,-1,-1,-1,-1])
out8 = sd.CoreAudioSettings(channel_map=[-1,-1,-1,-1,-1,-1,-1,0,-1,-1,-1,-1])
out9 = sd.CoreAudioSettings(channel_map=[-1,-1,-1,-1,-1,-1,-1,-1,0,-1,-1,-1])
out10 = sd.CoreAudioSettings(channel_map=[-1,-1,-1,-1,-1,-1,-1,-1,-1,0,-1,-1])
out11 = sd.CoreAudioSettings(channel_map=[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,-1])
out12 = sd.CoreAudioSettings(channel_map=[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0])

ca_in = sd.CoreAudioSettings(channel_map=[0,1])

def wavread(filename):#Reading 16bit WAVE files
    wf = wave.open(filename,'rb')
    buf = wf.readframes(wf.getnframes())
    data = np.frombuffer(buf, dtype = "int16")
    return data

TSP=wavread("tsp.wav")/small 
#Mettre en bruit blanc ou signal de signal sinusoïdal balayé (TSP)

#Calculer la réponse impulsionnelle de convolution
def IR(rTSPdata,outputfilename):
    rTSPdata=rTSPdata.T
    ipls=np.real(sp.ifft(sp.fft(rTSPdata)*sp.fft(np.flipud(TSP),rTSPdata.size)))
    c=np.fft.fftshift(ipls/max(ipls))
    int16amp=32768 / int(c.max())
    y2 = np.array([c * int16amp],dtype = "int16")[0]
    y4 = struct.pack("h" * len(y2), *y2)
    w = wave.Wave_write(outputfilename)
    w.setparams((
            1,                        # channel
            2,                        # byte width
            44100,                    # sampling rate
            len(y4),                 # number of frames
            "NONE", "NONE"  # no compression
        ))
    w.writeframesraw(y4)
    w.close()

#Playrec
def PlayRec(outmap,IDnumber):
    #sd.play(TSP,Fs,extra_settings=outmap,blocking=True)
    TSP1=sd.playrec(TSP,Fs,channels=2,extra_settings=(ca_in,outmap),blocking=True)
    TSP2=sd.playrec(TSP,Fs,channels=2,extra_settings=(ca_in,outmap),blocking=True)
    TSP3=sd.playrec(TSP,Fs,channels=2,extra_settings=(ca_in,outmap),blocking=True)

    #Nous faisons une polymérisation additive, mais nous avons récemment préparé un long bruit blanc ou signal Swept Sine (signal TSP).
    #Il semble que le courant dominant est de le trouver d'un seul coup sans polymérisation additive.
    
    rTSP = TSP1 + TSP2 + TSP3

    #Inversez la réponse enregistrée pour trouver l'IR
    rTSP1 = rTSP[:,0]
    rTSP2 = rTSP[:,1]
    rTSP3 = rTSP[:,2]
    rTSP4 = rTSP[:,3]
    rTSP5 = rTSP[:,4]
    rTSP6 = rTSP[:,5]
    rTSP7 = rTSP[:,6]
    rTSP8 = rTSP[:,7]
    rTSP9 = rTSP[:,8]
    rTSP10 = rTSP[:,9]
    
    #Nommez la réponse impulsionnelle résultante et écrivez-la dans un dossier en tant que fichier WAV
    IR(rTSP1,"IR"+str(IDnumber)+"1.wav")
    IR(rTSP2,"IR"+str(IDnumber)+"2.wav")
    IR(rTSP3,"IR"+str(IDnumber)+"3.wav")
    IR(rTSP4,"IR"+str(IDnumber)+"4.wav")
    IR(rTSP5,"IR"+str(IDnumber)+"5.wav")
    IR(rTSP6,"IR"+str(IDnumber)+"6.wav")
    IR(rTSP7,"IR"+str(IDnumber)+"7.wav")
    IR(rTSP8,"IR"+str(IDnumber)+"8.wav")
    IR(rTSP9,"IR"+str(IDnumber)+"9.wav")
    IR(rTSP10,"IR"+str(IDnumber)+"10.wav")

print("Commencer la mesure")
PlayRec(out1,1)
PlayRec(out2,2)
PlayRec(out3,3)
PlayRec(out4,4)
PlayRec(out5,5)
PlayRec(out6,6)
PlayRec(out7,7)
PlayRec(out8,8)
PlayRec(out9,9)
PlayRec(out10,10)
PlayRec(out11,11)
PlayRec(out12,12)
print("Fin de la mesure")

référence

Officiel du périphérique audio Python Module de traitement du périphérique audio pouvant être utilisé avec le périphérique Python-Sound ASIO [Basic]

Recommended Posts

Module de traitement du signal acoustique qui peut être utilisé avec Python-Sounddevice ASIO [Application]
Python-Sound device Module de traitement du signal acoustique ASIO [Basic]
Types de fichiers pouvant être utilisés avec Go
Notes sur les connaissances Python utilisables avec AtCoder
Traitement du signal acoustique avec Python (2)
Traitement du signal acoustique avec Python
Module standard Python utilisable en ligne de commande
Remplissage facile des données pouvant être utilisées dans le traitement du langage naturel
Optimisation mathématique pour un travail gratuit avec Python + PuLP
Jusqu'à ce que vous puissiez utiliser youtube-dl avec Synology (DS120j)
Fonctions pouvant être utilisées dans l'instruction for
Aucun module nommé'distutils.util 'ne peut être utilisé avec get-pip.py
Répertorier les packages pouvant être mis à jour avec pip
Module de grattage "Gaspacho" qui peut être utilisé plus facilement que Beautiful Soup
Convertir des images du SDK FlyCapture en un formulaire pouvant être utilisé avec openCV
[Python] Introduction au scraping WEB | Résumé des méthodes pouvant être utilisées avec webdriver
Serveur de partage de fichiers réalisé avec Raspberry Pi pouvant être utilisé pour le travail à distance
Algorithmes de base utilisables par les pros de la compétition
Pour pouvoir utiliser le japonais avec Python dans l'environnement Docker
Liste des couleurs pouvant être définies avec tkinter (mémorial)
Enregistrement d'image ANT qui peut être utilisé en 5 minutes
[Django] À propos des utilisateurs pouvant être utilisés sur un modèle
Limites qui peuvent être analysées à la fois avec MeCab
Récapitulatif du format des formats qui peuvent être sérialisés avec gensim
Il semble que le suivi des squelettes puisse être effectué avec RealSense
pd.tseries.offsets.DateOffset peut être assez lent s'il n'est pas utilisé avec prudence
Goroutine (contrôle parallèle) utilisable sur le terrain
Goroutine utilisable sur le terrain (édition errgroup.Group)
SSD 1306 OLED peut être utilisé avec Raspeye + python (Remarque)
Scripts pouvant être utilisés lors de l'utilisation de Bottle en Python
Traitement du signal acoustique à partir de Python - Faisons un système acoustique en trois dimensions
J'ai étudié le prétraitement qui peut être fait avec PyCaret
Faisons un diagramme sur lequel on peut cliquer avec IPython
J'ai essayé de l'étendre pour que la base de données puisse être utilisée avec le logiciel d'analyse de Wiire
Comprendre les probabilités et les statistiques qui peuvent être utilisées pour la gestion des progrès avec un programme python
À propos du fait que le résumé de la torche peut être vraiment utilisé lors de la construction d'un modèle avec Pytorch
[Python] Créez un graphique qui peut être déplacé avec Plotly
Jusqu'à ce que la géométrie de la torche ne puisse être utilisée qu'avec le processeur Windows (ou Mac)
Créez une Spinbox qui peut être affichée en binaire avec Tkinter
Un minuteur (ticker) qui peut être utilisé sur le terrain (peut être utilisé n'importe où)
J'ai fait un shuffle qui peut être réinitialisé (inversé) avec Python
Développement d'applications IOS avec Python (kivy) que même les singes peuvent faire
Créez un graphique des devises qui peut être déplacé avec Plotly (2)
Résumé de l'entrée standard de Python pouvant être utilisée dans Competition Pro
Comparaison de 4 styles pouvant être passés à seaborn avec set_context
Créez une Spinbox pouvant être affichée dans HEX avec Tkinter
Créez un graphique des devises qui peut être déplacé avec Plotly (1)