0
$\begingroup$

I'm trying to record sounds in chunks using PyAudio for 15 seconds, chunk size being 1024 and sampling rate is 1024 *40. I understand the number of chunks would be (time of recording) * (sampling rate) / (chunk size).

However, when I timed the time it takes for the for loop to finish, it's much longer than 15 seconds, around 2 than 3 times longer than expected. I wonder why? Granted I have a lag in each loop to display the FFT of each chunk, but that's only 0.001 second.

Is this because Windows is not a real time system?

import time
import image
import numpy as np
import os
import pyaudio
import matplotlib.pyplot as plt
from scipy.fftpack import fft


CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 1024*40
RECORD_SECONDS = 15

p = pyaudio.PyAudio()
stream = p.open(format=FORMAT,
                channels=CHANNELS,
                rate=RATE,
                input=True,
                frames_per_buffer=CHUNK)

input('Press key to start recording:\n')
print('2 sec delay started')
time.sleep(2)
print("* recording")

n = CHUNK
k=np.arange(n)
T = n/RATE #reciprocal of freq resolution
frq = k/T #k* freq resolution for plotting
window=np.hanning(n) #apply Hanning window to minimize spectrum leakage
num_frames=int(RATE*RECORD_SECONDS/CHUNK)

for i in range(0, num_frames):
    data = stream.read(CHUNK)
    decoded = np.frombuffer(data, dtype=np.int16)
    #decoded= decoded/2**15
    windowed=window*decoded
    fft_decode=fft(windowed)/(len(decoded)/2)
    mags=np.absolute(fft_decode)

    plt.ylim(top=200)
    plt.xlabel('Freq (Hz)')
    plt.ylabel('|Y(freq)|')
    plt.plot(frq[range(int(n/2))], mags[range(int(n/2))],'b') 
    plt.pause(.001)
    plt.gcf().clear()


print("* done recording")
plt.close()
$\endgroup$
2
$\begingroup$

First off, a small thing:

The sampling rate usually has to be one of the standard sampling rates. Closest to your 1024*40 would be 44100.

The hardware has to support the sampling rate. Some drivers will resample to the given rate, but that will be somewhat slow as it is in software. Try using a proper sampling rate.

The real bottle neck is the plotting.

Your are calculating the FFT for every block, and plotting it.

The FFT is blazing fast, no worries there.

Plotting on the other hand is horribly slow. The plotting routine is not optimized for speed, and you are also rescaling and formatting the plot on every go around.

Comment out the lines that do the plotting. Leave the FFT in. You'll see a tremendous change in speed.


Edit: Just noticed. Besides plot being slower than molasses, you also have a pause in there. It is only 1 millisecond, but I don't know how precise it really is. Many timers under Windows use 15 millisecond steps, so that pause could be zero, or 1 millisecond, or 15 milliseconds.

In any case, it is not doing you any good. Take it out.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.