pythonwindowspyaudio

check if any devices on windows are playing sound python


I'm trying to detect system sounds on windows and I figured I could use the pyaudio module since winrt didn't work for me. I've got this code that lists all the devices, and I know I can open streams with pyaudio

import pyaudio
p = pyaudio.PyAudio()
for i in range(p.get_device_count()):
    dev = p.get_device_info_by_index(i)
    print(dev)

but how can I tell whether any of these devices are currently outputting sound? Do I open a stream for each one and take the mean square root of the bytes? If this is an XY problem and I'd be better off using another module, please let me know


Solution

  • In python I didn't find any very effective module to retrieve the internal audio of a pc, rather I found a way to simulate the output devices as Input using Stereo Mixer on windows platform.

    First enable Stereo Mixer on your windows environment.

    After that find the index on which the stereo mixer is located using this code :

    import pyaudio
    p = pyaudio.PyAudio()
    for i in range(p.get_device_count()):
        print("\n\n Index " + str(i) + " :\n")
        dev = p.get_device_info_by_index(i)
        print(dev.get('name'))
        print("------------------------------------------------------------")
    

    This code will list all the audio devices along with their indexes. Note the index of Stereo Mixer in your pc.

    Here comes the main code to detect sound, replace the device variable's value with the index of Stereo Mixer. For me it was 2.

    import pyaudio
    import audioop
    
    p = pyaudio.PyAudio()
    CHUNK = 1024
    FORMAT = pyaudio.paInt16
    RATE = 44100
    silent_threshold = 1
    
    device = 2
    stream = p.open(format=FORMAT, channels = p.get_device_info_by_index(device).get('maxInputChannels') , rate=RATE, input = True ,  frames_per_buffer=CHUNK , input_device_index = device)
    
    while True:
        
        data=stream.read(CHUNK)
        threshold = audioop.max(data , 2)
        print(threshold)
        if  threshold > silent_threshold :
            print("Sound found at index " + str(device))
        else :
            print("Sound not found at index " + str(device))
    
    p.terminate()
    

    Note the use of silent_threshold, the more you increase its value the less reactive it becomes. For example if you want to detect absolute silence use 1 or to detect quietness use 20 , it depends upon your sound playback on your pc.