bastibe / SoundCard

A Pure-Python Real-Time Audio Library
https://soundcard.readthedocs.io
BSD 3-Clause "New" or "Revised" License
689 stars 70 forks source link

how to get non numpy "raw" mono data from the record() method #172

Closed bespsm closed 1 year ago

bespsm commented 1 year ago

using classical example of recording audio from speaker, I can easily save the data to the file using "soundfile" library. What if I want to use raw data (bytes) further it in my app, how can I convert it?

from pydub import AudioSegment
import soundcard as sc
import soundfile as sf

if __name__ == '__main__':
    OUTPUT_FILE_NAME = "out.wav"    # file name.
    SAMPLE_RATE = 16000              # [Hz]. sampling rate.
    RECORD_SEC = 3                  # [sec]. duration recording audio.

    with sc.get_microphone(id=str(sc.default_speaker().name), include_loopback=True).recorder(samplerate=SAMPLE_RATE, channels=1) as mic:
        # record audio with loopback from default speaker.
        data = mic.record(numframes=SAMPLE_RATE*RECORD_SEC)

        # works well
        sf.write(file=OUTPUT_FILE_NAME, data=data, samplerate=SAMPLE_RATE)

        # gives over amplified noised sound
        # asa = AudioSegment(data=data.tobytes(),channels=1,sample_width=4,frame_rate=SAMPLE_RATE)
        # asa.export("out.wav", format="wav")  

any guess?

bespsm commented 1 year ago

for those who are also looking the answer, data can be scaled to the different format pcm_s16le, this way it has no noise scaled = np.int16(data / np.max(np.abs(data)) * 32767)

bastibe commented 1 year ago

Soundcard gets float data from the OSs' audio APIs. It returns that data as float numpy arrays. What you get is the raw data. int16 PCM is only the default in WAV files, but there's nothing "raw" about it.