0
$\begingroup$

Im doing some beginners spectral analysis for a homemade reactive RGB LED project and was thinking of ways to improve the accuracy of the audio analysis. Im using a Playstation eye with a Raspberry Pi Zero W (limited performance) and ive read several articles to try to better my understanding. According to this article, the playstation eye has 4 channels, where the 2nd and 3rd are reversed for noise cancellation.
I assume that the 2nd channel is a reverse of the 1st and the 3rd of the 4th. Am i correct to assume that the way to go about implementing these extra channels would be to average the two sums of 1+2 and 3+4 ie. voltage = (c1+c2+c3+c4)/2?

Below is a script i use for testing, only the basics. Note that i use a sampling rate of 20khz instead of 44.1khz due to the limited cpu resources of the pi zero. I also use int16 as wiki states that the ps eye uses 16bit ints. Am i wrong not to use the default float?

The reason i want to improve it is that i havent recorded any frequencies over 7000, which seems a bit odd to me given the vast variety of music ive tested with. Im wondering if the playstation eye is not suitable for such precise analysis, or if my methods are wrong. Is it possible to improve this with noise cancellation, or will it worsen my results? Should i rather just use a single channel or sum channel 1+4?

#!/usr/bin/env python3

import sounddevice as sd
import numpy as np

RATE = 20000
lowest = 200
highest = 0
h_m = 0

def print_sound(indata, frames, time, status):
    global lowest, highest, h_m
    if status:
        print(status)
    if frames == 0:
        return
    data = np.sum(indata, axis=1)
   # data = data * np.hanning(len(data)) # smooth the FFT by windowing data
    fft = abs(np.fft.rfft(data)) # calculate magnitudes from positive fft coefficients
    freq = np.fft.rfftfreq(frames, 1.0/RATE) # calculate positive frequency bins
    max = np.max(fft) # highest magnitude
    freqPeak = freq[np.where(fft==max)[0][0]] # find frequency with highest magnitude
    if freqPeak < lowest:
        lowest = freqPeak
        print("lowest: %d"%freqPeak)
    if freqPeak > highest:
        highest = freqPeak
        print("highest: %d"%freqPeak)
    if max > h_m:
        h_m = max
        print(max)

with sd.InputStream(dtype='int16', channels=4, samplerate=RATE, callback=print_sound):
    while True:
        response = input()
        if response in ('', 'q', 'Q'):
            break
$\endgroup$
  • $\begingroup$ The way I interpret this reversal is that the second and third channel simply has a $-$ in front of it, not that they are the reversed versions of the other two. That would not be 4 channel audio. The Eye can do 48 kHz but maybe the drivers in your architecture are not going any higher than ~16k (?). $\endgroup$ – A_A Dec 29 '18 at 15:15
  • $\begingroup$ According to the article they are phased waves and their amplitude is a bit lower. Yes the eye can do 48khz, but my Pi Zero doesnt have enough computational power to handle that. Even at 44.1khz i get input overflow, ie. too much cpu time spent, so some input in the buffer gets discarded because it fills faster than its emptied $\endgroup$ – LuqJensen Dec 29 '18 at 20:46
0
$\begingroup$

As I read your prompt, it seems that the real question you’re asking is why you can’t record frequency peaks greater than 7kHz. The second question seems to be whether you can improve this performance through noise cancellation techniques.

If that’s the case, and if you’re right about the 2nd and 3rd channels being reversed, then I think your summation may introduce frequency filtering effects in your output and not necessarily true noise cancellation. This can either work for or against you. But this would depend on the orientation between the microphone and speakers, since in your link it appears that can affect the delays between the channels. Either way, I’d go with the single channel to simplify things.

And if you’ve only been recording music and not individual tones at greater than 7kHz, then it also makes sense that you’re not grabbing high frequency peaks since audio energy tends to be concentrated at lower frequencies. There’s a reason why telephones and AM radio cut off at around 5kHz. You might also be attenuated because of sinc roll off during the sampling process, although I suspect that’s not the big issue here.

Have you tried recording the entire spectrum, instead of just the peaks? And have you tried comparing that against the FFTs of the original audio files?

$\endgroup$
  • $\begingroup$ Yes im looking at the peaks, because i use them to flash the RGB LED. Looking at the entire spectrum wouldnt make much sense in that case. No i havent directly compared the fft to the fft from the files, i only took a brief look at some in audacity. And i would believe you are correct that there are indeed higher frequencies present in the recordings, they are just never the peaks. What got me wondering if i did it right was the fact that bell sounds from simple audio files did not produce frequencies over 6khz either. But perhaps their majority of magnitude is below 6khz $\endgroup$ – LuqJensen Dec 30 '18 at 10:28

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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