makerportal/rpi_i2s

questions about data normalization in the function of data_grabber(rec_len)

snownstone opened this issue · 5 comments

Thank you very much for your tutorials and codes.

I noticed that in the function of data_grabber(rec_len), after you got the raw data from the pyaudio stream, you did not normalize it by dividing 2**15 (say the format is np.int16). I want to know if you realized it and if there is a good reason of the current choice.

No reason in particular, except that there could be a slight delay in the acquisition. It might be a better idea to normalize the entire array after acquiring the data. Normalization is always a good idea. Thank you for adding that.

I am trying to do real-time fft to audio stream data and find the processes in different codes are not exactly the same, so I was trying to figure out what the standard and complete way is. Now I understand it more. Your tutorials are very helpful to me. Thank you for your sharing.

Dear Joshua, I just had another question about data acquisition time. As you mentioned it before, I wondered if you could help me.

I want to do real-time music beat tracking according to the way introduced by Frédéric Patin. I thought the time for chunk data analyses and beat detection should be less than the time for chunk data-grabbing from the stream, so I was checking it. Then I noticed that the time for chunk data-grabbing sometime is unreasonably short, much shorter than 0.023s (1/44100*1024) as shown in the picture below. When this happened, I guess pyaudio (or portaudio) did not grab the data as the chunk size as I defined (1024), but I do not know why this happened. Did I do anything wrong or do you have any idea about it?

Thank you.

reading_time_resolution

The reason for this is that the pyaudio is actually grabbing from the buffer stream. So you are grabbing data from previously, not right at the moment you are grabbing it (give or take a few milliseconds, as you see in your printout). This is why we keep the chunk grabbing shorter (1024 or so); so that we don't overflow the buffer. It's a nuanced process, which you may want to play with for your particular application. For example, it may be useful for your application to look into precise starting/stopping of the stream while doing processing.

I hope this helps!

-Josh

Josh, thank you very much for your explanation and help. As I am a newbie both in programming and dsp, it takes me time to figure things out following your lead, especially the concepts of buffer both in hardware and software sides. Now I realized that there are more things to consider about timing and the flow of stream data from input, through process, to the output. Below I attached the refs which I found helpful in case anyone else had similar confusions.

Thank you again.

Liuqing :)

PyAudio behavior during time.sleep()

Audio Latency

Introduction to Sound Programming with ALSA