I want to make color music on Raspberry Pi, I know how to work with LED strip. The moc player is installed in rpi, the music plays in it. How do I get the current frequencies from the python script to transfer them to the LED strip?

  • Perform Fourier analysis of the current frame, if rpi performance allows. - mkkik

1 answer 1

As an example from which to start, you can write something like this:

import requests import matplotlib.pyplot as plt import numpy as np from io import BytesIO import wave import pyaudio test_wav_request = requests.get("http://download.wavetlan.com/SVV/Media/HTTP/WAV/Media-Convert/Media-Convert_test6_PCM_Stereo_VBR_16SS_8000Hz.wav") if test_wav_request.status_code != 200: print("Не могу скачать WAV. Код:", test_wav_request.status_code) exit(1) wav_file = BytesIO(initial_bytes=test_wav_request.content) wav = wave.open(wav_file) (nchannels, sampwidth, framerate, nframes, comptype, compname) = wav.getparams() # content = wav.readframes(nframes) width_to_bits = {1: np.int8, 2: np.int16, 4: np.int32} width_to_bits_ = {1: 8, 2: 16, 4: 32} width_pyaudio = {1: pyaudio.paInt8, 2: pyaudio.paInt16, 4: pyaudio.paInt32} audio = pyaudio.PyAudio() stream = audio.open(format=width_pyaudio[sampwidth], channels=nchannels, rate=framerate, input=False, output=True) print((nchannels, sampwidth, framerate, nframes, comptype, compname)) sample_size = 4 * 512 def normalize(samples, bits_per): return [s / 2**bits_per for s in samples] # Для примера возьмем последовательно 4 сэмпла размером 4*512 кадров. # Для данного файла частота 8000 кадров в секунду, то есть возьмем кадров за 0.25 секунд stream.start_stream() for i in range(1, 5): sample = wav.readframes(sample_size) # Для данного файла точно известно, что количество каналов 2 data = normalize(np.fromstring(sample, width_to_bits[sampwidth]), width_to_bits_[sampwidth]) stream.write(sample) left_channel = data[::2] right_channel = data[1::2] furier_left = np.abs(np.fft.rfft(left_channel)) furier_right = np.abs(np.fft.rfft(right_channel)) # Не знаю, что делают с разными каналами, но можно их объединить spectrum = np.hstack((furier_left[: int(len(furier_left) / 2)], furier_right[: int(len(furier_right) / 2)])) Hz = np.fft.fftfreq(len(left_channel), d=0.25) Hz *= framerate # По какой-то неизвестной причине в furier_left лишний элемент plt.subplot(2, 2, i) plt.plot(Hz[:len(Hz) // 2], 10 * np.log10(furier_left[:-1])) plt.ylabel("dB") plt.xlabel("Hz. Number: " + str(i)) stream.stop_stream() plt.show() 

This script will download the test wav file with the bleating of a sheep, and build 4 graphs - every 0.25 seconds, the sound is extracted, normalized, and the Fourier transform is performed. Then it calculates the decibel values ​​and displays the graph - along the X axis - Hertz, along the Y axis - Decibels. Here is one of the graphs - http://imgur.com/j1ApCEB . 4 graphics in one picture: http://imgur.com/vgQq0YA Honestly, I don’t know if this looks like an "equalizer" because Google says that the equalizer is a device.

  • Thank you very much! I'll try! Well, how do they render the same in WinAmp, and in moc there is also - Jeid
  • one
    I can’t say that the axes are not signed anywhere. I think about the same. You can take any number of octaves and average the results on them - then you’ll get not a graph, but a histogram, just like in WinAmp-like visualizations. You can take values ​​not decibels, but simply the coefficients after Fourier - should also jump in time in different directions. - m9_psy
  • Yes, this is where the question arises, how to get these values ​​from the current audio stream? - Jeid
  • one
    @Jeid, using moc is unlikely to get a raw stream - moc is a third-party application, not a library for Python, and not a fact that it has such capabilities. I'll add an example with PyAudio to the answer. - m9_psy
  • one
    @Jeid, I updated the example with audio playback. You can see only changes in history. Similarly, it can be repeated with libraries for other formats, for example, PyMedia or pygame - all of them have similar APIs. My example is not very functional, because it displays graphs after playback - this is easily changed using the animate method of matplotlib . You may have to use the library faster. For example, plotly. The most difficult thing here is Fourier and all that is connected with it, and in comparison with this, the draftsmen are trivial. - m9_psy