bastibe/SoundCard

Using version 0.4.2, when recording Xiaomi microphones on Win11, the response was that there was no valid sound in the data,

tbUoky opened this issue · 4 comments

Hi,i use the version 0.4.2 on Win11,use the Xiaomi microphones, the returned result cannot form an audio file with actual audio content.

the get mic data code

import soundcard as sc
import wave
import numpy as np
FILE_NAME = "111.wav"

framerate = 16000
channels = 1
blocksize = 1600
print(sc.default_microphone().channels)
datas = []
with sc.get_microphone(id=str(sc.default_microphone().name), include_loopback=True).recorder(samplerate=framerate, blocksize=blocksize, channels=channels) as mic:
    for i in range(0, 50):
        frames = mic.record(numframes=blocksize)
        if frames.dtype == "float64":
            datass = (frames *np.iinfo(np.int16).max).astype(np.int16)
        if frames.dtype == "float32":
            datass = (np.array(frames) * 32767).astype(np.int16)
        data = datass.tobytes()
        # data = frames.tobytes()
        datas.append(data)
    print("start to file")
    with wave.open(FILE_NAME, 'wb') as wf:
        wf.setnchannels(channels)
        wf.setsampwidth(2)
        wf.setframerate(framerate)
        for data in datas:
            wf.writeframes(data)

but get the speaker data is ok

import soundcard as sc
import wave
import numpy as np
FILE_NAME = "222.wav"

framerate = 16000
channels = 1
blocksize = 1600
print(sc.default_speaker().channels)
datas = [] 
with sc.get_microphone(id=str(sc.default_speaker().name), include_loopback=True).recorder(samplerate=framerate, blocksize=blocksize, channels=channels) as mic:
    for i in range(0, 50):
        frames = mic.record(numframes=blocksize)
        if frames.dtype == "float64":
            datass = (frames *np.iinfo(np.int16).max).astype(np.int16)
        if frames.dtype == "float32":
            datass = (np.array(frames) * 32767).astype(np.int16)
        data = datass.tobytes()
        # data = frames.tobytes()
        datas.append(data)
    print("start to file")
    with wave.open(FILE_NAME, 'wb') as wf:
        wf.setnchannels(channels)
        wf.setsampwidth(2)
        wf.setframerate(framerate)
        for data in datas:
            wf.writeframes(data)

i see the mic properties, it looks no different from the built-in microphone array on the computer. It is both 2-channel 16 bit, 48000Hz,
But when running the code using the computer's microphone array, the returned audio is normal and clear
image
please help me or give me some advice , Thank you very much

Some sound cards to not play nice with non-default samplerates. It may be that yours bugs out if you request 16 kHz. (Also, microphone driver quality varies WILDLY)

Some sound cards to not play nice with non-default samplerates. It may be that yours bugs out if you request 16 kHz. (Also, microphone driver quality varies WILDLY)

I saw a sampling rate of 48kHz corresponding to the headphones in the properties, but the test results were even worse, with only a sizzling sound in the audio
I need to obtain the audio stream of the fixed block in real-time. Initially, I used pyaudio, but obtaining the sound from the speakers requires stereo mixing to be turned on, so I adjusted it to soundcard. Perhaps you can give me some advice?
I haven't been using Python for long, thank you very much

Fixed block rates are not generally possible with different sound cards. Sampling rates always drift slightly, so two sound cards will never stay in sync for long. They typically drift on the order of a few seconds per hour. You'll always need to stretch the audio slightly, or re-cut it into matching blocks.

There are only two solutions to this that don't require such external synchronization:

  1. Record and play on the same sound card
  2. Use pro audio gear with an external clock source

Fixed block rates are not generally possible with different sound cards. Sampling rates always drift slightly, so two sound cards will never stay in sync for long. They typically drift on the order of a few seconds per hour. You'll always need to stretch the audio slightly, or re-cut it into matching blocks.

There are only two solutions to this that don't require such external synchronization:

  1. Record and play on the same sound card
  2. Use pro audio gear with an external clock source

Last week, I recorded the speaker normally, but this week I couldn't record properly and couldn't find the reason. Finally, I used Conda to create a 3.9 Python environment. After reinstalling the dependency, I was able to obtain the sound of the speaker and microphone normally. The Python environment I used before was 3.11.5,Thank you very much for your help