Let's Build an Audio Spectrum Analyzer in Python! (pt. 3) Switching to PyQtGraph

Поделиться
HTML-код
  • Опубликовано: 1 фев 2025

Комментарии • 106

  • @pkl520
    @pkl520 7 лет назад +12

    thanks for sharing such great tutorials. luv ur channel

    • @MarkJay
      @MarkJay  7 лет назад +1

      pkl520 you're welcome! Glad you like them!

  • @lutetube88
    @lutetube88 2 года назад +1

    Great stuff!, Nice job on the video and the work on the program. I done some similar stuff on C#. I'm more of a beginner/ with python and pyqtgraph. Not much book subjects on it. I know the PyQt 4 is well outdated so I have struggle with getting some of the code to work, but have managed to get the waveform side of your code to work. Really appreciate the video, using mostly to learn and study. Recently bought the book " Create GUI Applications with Python & Qt5". Good book but missing at lot on pyqtgraph. Thanks again for the video!

  • @LookNumber9
    @LookNumber9 5 лет назад

    Beautifully paced and explained. Thank you!

  • @BrendenVogt
    @BrendenVogt 4 года назад

    Nice tutorial!. Thank you for that PyAudio and PyQtGraph is my new favorite plotting tool

  • @janisreinberger7724
    @janisreinberger7724 6 лет назад +9

    If someone else needs to filter out some noise that occurs when there is no active input, add "sp_data[sp_data

  • @vito135c
    @vito135c 3 года назад

    Great video now I'm your new subscriptor, please continue.

  • @bitpilot79
    @bitpilot79 7 лет назад +2

    Really like your tutorials, keep up the good work.

    • @MarkJay
      @MarkJay  7 лет назад

      totex1979 thank you!

  • @demonicsweaters
    @demonicsweaters 6 лет назад +1

    Excellent tutorial!

  • @Ines-xk5jy
    @Ines-xk5jy 6 лет назад +8

    This is awesome! I just have one question. How could i save the entire audio, waveform and spectrum?

  • @staalklang
    @staalklang 3 года назад +4

    Thank you for the video and sharing your code. I found a float operator bug at line 63 on your github. Using Python 3.9. You should use double // since it expect an integer not a float.. Line 63 should look like this: self.f = np.linspace(0, self.RATE / 2, self.CHUNK // 2)

  • @vladbuga3354
    @vladbuga3354 6 лет назад +4

    How to obtain the spectrum, when you read from a .mp3 file?

  • @dorzamir4888
    @dorzamir4888 25 дней назад

    hey one again great videos an tutorieals
    i have a question if i want that my sorce not be from the microfon i want that from my directory from my pc what i need to change

  • @scrapolio7885
    @scrapolio7885 5 лет назад +3

    I’m having a problem where the spectrum won’t show, I get a warning saying “run time warning divide by zero encountered in log10”

    • @rwharrington87
      @rwharrington87 4 года назад

      I have the same issue.

    • @micromouseonline
      @micromouseonline 4 года назад +2

      around line 64 ish there should be a statement like
      self.f = np.linspace(0, self.RATE / 2, int(self.CHUNK / 2))
      change it to
      self.f = np.linspace(1, self.RATE / 2, int(self.CHUNK / 2))

    • @greivinsalas354
      @greivinsalas354 4 года назад

      @@micromouseonline you're a god

    • @alexchui4672
      @alexchui4672 4 года назад

      @@micromouseonline after changed the waveform is displaying. but still, the spectrum isn't showing. any ideas?

    • @micromouseonline
      @micromouseonline 4 года назад

      Alex Chui sorry. I have not looked at this in ages.

  • @garylawman9132
    @garylawman9132 2 года назад

    Thanks for your hard work - Python 3.10.6 fixes:
    1. # pyaudio stuff
    self.CHUNK = 2048 * 8 #GG Was 1024 * 2 - works 2048 * 8
    2. # waveform and spectrum x points
    self.x = np.arange(0, 2 * self.CHUNK, 2)
    self.f = np.linspace(0, int (self.RATE / 2), int (self.CHUNK / 2))
    3. Unable to fix:
    DeprecationWarning: Accessing pyqtgraph.QtWidgets through QtGui is deprecated and will be removed sometime after May 2022. Use QtWidgets.QApplication instead.

  • @JakeyBrakey
    @JakeyBrakey 6 лет назад +1

    Thanks for the awesome tutorial, but I have a question, I noticed at the bottom you received a divide by 0 error when running the program around 18:45. I also ran this program on my machine and encountered the same error while running the window. Should this error be of concern?

    • @MarkJay
      @MarkJay  6 лет назад

      Trigger I don't think it was a major issue. You shouldn't need to worry about it. But you can always use a try statement to avoid the error

    • @JakeyBrakey
      @JakeyBrakey 6 лет назад

      Mark Jay Thanks for the help man

  • @vhagarmusic
    @vhagarmusic 2 года назад

    Loved the tutorial. I just wanted to ask one question. Instead of taking input from the mic, can we optimize it to listen to mp3 files stored in our system only?

    • @MarkJay
      @MarkJay  2 года назад

      Thanks. Yes of course. It could be any audio file instead of a mic

  • @jeetshah8513
    @jeetshah8513 4 года назад +1

    Hey, I have a doubt
    If I have a music sample which has two components of say guitar and piano.
    SO is there any way we can split that sample into ins components?

  • @Sapperbounded
    @Sapperbounded 5 лет назад +1

    Copying the code in your github I can't seem to get anything to display for the spectrum part of the graph. I keep getting divide by zero encountered in log10.

  • @nitro-tree
    @nitro-tree 3 года назад +1

    Why does the spectrum not display like in version 2?

    • @MarkJay
      @MarkJay  3 года назад

      Not sure, but they should be similar. I think I used the same code

    • @nitro-tree
      @nitro-tree 3 года назад

      @@MarkJay oh, I think what I meant was why does the purple spectrum on v2 not have peaks like in v1. It kinda just levels out. I was going to use this info to display it onto a series of led lights I have to make an analyzer on my wall.

  • @el07694
    @el07694 4 года назад

    Nice videos. Thanks

  • @toddlight8982
    @toddlight8982 4 года назад

    Thanks for the instruction and explanations. Did you go on to produce the code for a 3D animated spectrograph display that you mentioned? If so, is it available?

  • @liliansirbu840
    @liliansirbu840 4 года назад

    Hi, can you add some controls in your window, like volume knobs and buttons ?

  • @hakobhakobyan2856
    @hakobhakobyan2856 5 лет назад +1

    I have a problem with ploting data from serial port, it remembers only first 200 values, could you please help me with this ?

  • @redronit
    @redronit 3 года назад

    Hello, would there be a way to dump the processed frequency instead of graphically in text? Thanks Mark!

  • @cornchip45
    @cornchip45 2 года назад

    Hi, I am trying to add some peak detection to the fft. I added another method to find the peaks that gets called in the "update" method, and I added the peak locatiosn as arguments to the "set_plot" data function. For now, I am just trying to plot the peak tips as a scatter plot overlay of the fft plot, but it isn't quite working, my problem is that only the first set of peaks gets plotted, and it never updates. I'm totally new to PyQtGraph so I'm not quite sure what to do.
    Do I need to add more arguments to self.traces[name].setData(data_x, data_y)? Do I need to make another self.waveform.plot() call?
    Also, at the end of the day, I'm want to put text labels over the highest peak that shows its frequency, but I couldn't find any doccumentation in PyQtgraph that explains how. if you have any tips I would appreciate it!

  • @amine-_-119
    @amine-_-119 6 лет назад +1

    Great 👍👍👍
    Plz how can i add the filtered signal too into this GUI.. i dont know how to do filters in python (low pass band pass high pass..) can u do tutorial on filtering audio in real time

    • @liliansirbu840
      @liliansirbu840 4 года назад

      i like this idea, I sustain it too )

  • @samiraziur09
    @samiraziur09 6 лет назад

    Hi Mark... Thanks for the help last time... i was trying to run the matplotlib version of the spectrum analysis... but the graph is not showing up... I was able to run and see the audio analyzer for the first video. I am using Pycharm and exactly copied your github code to run the program. Thanks in advacne...

  • @randythamrin5976
    @randythamrin5976 4 года назад +1

    i have a problem with these line
    self.x = np.arange(0, 2 * self.CHUNK, 2)
    self.f = np.linspace(0, self.RATE / 2, self.CHUNK / 2)
    TypeError: object of type cannot be safely interpreted as an integer.

    • @randythamrin5976
      @randythamrin5976 4 года назад +1

      this is the answer
      self.x = np.arange(0, 2 * self.CHUNK, 2)
      self.f = np.linspace(0, int (self.RATE / 2), int (self.CHUNK / 2))
      thanks for Floyd Scott
      4 months ago

    • @augustnicolaybroch9829
      @augustnicolaybroch9829 4 года назад

      @@randythamrin5976 Thanks! :D Had the same error, and this solved it for me

    • @isaaca.cruzmedina6667
      @isaaca.cruzmedina6667 4 года назад

      @@randythamrin5976 hi, I tried with this, but only I can see the waveform, I can't see the spectrum yet. Any idea?

    • @randythamrin5976
      @randythamrin5976 4 года назад

      @@isaaca.cruzmedina6667 sorry, with same error as mine?

  • @zahidulislam9812
    @zahidulislam9812 6 лет назад +1

    sir please can you make a video how can we save this recorded video in wav format and slice them in to small part (means real voice not noise)

  • @jimmyclock9072
    @jimmyclock9072 4 года назад +1

    keep getting this error
    num = operator.index(num)
    TypeError: 'float' object cannot be interpreted as an integer
    ...
    TypeError: object of type cannot be safely interpreted as an integer.

    • @floydwscott
      @floydwscott 4 года назад

      self.f = np.linspace(0, self.RATE / 2, self.CHUNK / 2)
      RATE and CHUNCK are being changed to a float by /2
      self.f = np.linspace(0, int(self.RATE / 2), int(self.CHUNK / 2))
      made it work for me

    • @floydwscott
      @floydwscott 4 года назад

      self.f = np.linspace(0, self.RATE / 2, self.CHUNK / 2)
      RATE and CHUNK are being changed to a float by /2
      self.f = np.linspace(0, int(self.RATE / 2), int(self.CHUNK / 2))
      made it work for me

    • @volkovolko
      @volkovolko 4 года назад

      @@floydwscott i had the same idea

  • @bennguyen1313
    @bennguyen1313 4 года назад

    It seems the syntax for matplotlib and PyQt-Graph is not compatible. Any thoughts on when one may be better suited over the other?
    I'm trying to plot real-time data coming in from the serial port, but I start to lose data after a few seconds.. any suggestions on either using concurrency (queue/collections.deque, threading, asyncio, multiprocessing) or whether to use matplotlib-blit, or PyQtGraph-split... or PyQt vs tkinter.... or any approach that would maximize the throughput so that no data gets dropped from the serial during the GUI update?
    I'm running on a PC, but I saw an example of a fast oscilloscope on a Raspberry Pi using OpenGL/freeglut , however, the use of the GPU looks intimidating and perhaps overkill for my needs!

    • @MarkJay
      @MarkJay  4 года назад

      Probably pyqtgraph is best for plotting data fast, but I'm not sure how to prevent data from being lost when trying to plot. In audio I believe a circular buffer is used to queue up samples to be played so maybe some thing similar for plotted data. Just a thought tho

    • @bennguyen1313
      @bennguyen1313 4 года назад

      ​ @Mark Jay Thanks! I noticed that updating using something like, self.x = np.append(self.x, random.randint(0,10) ), self.plot( self.x, self.y ) , I get framerates that start at around 60, but continuously slows down as more points are added... ex. 3 fps with a mere 200 points! Does this sound normal?

  • @viniciuscampos2144
    @viniciuscampos2144 5 лет назад +1

    IF I need read an AUDIO File and show the FFT in real time the code changes too much?

  • @Mecca0497
    @Mecca0497 6 лет назад

    I have a project that also using spectrum analyzer but... since I'm still new to this whole audio spec and so I have question....
    can we inserting some frequency number displayed too? example 195.000Hz at it's peak when played some sound then sound stop, it goes back again to 0Hz
    (trying to creating violin tuner like that)

    • @MarkJay
      @MarkJay  6 лет назад +1

      you can definitely add a marker at 195Hz using the method I showed in the video. there's definitely ways to do what you want with pyqtgraph.

    • @Mecca0497
      @Mecca0497 6 лет назад

      Mark Jay Thank you, I'll try it right away

    • @Mecca0497
      @Mecca0497 6 лет назад

      could you please take a look this codes github.com/mecca0497/audio-tuning
      which marker should I add so I can show your audio spectrum?

  •  5 лет назад +1

    Spevtrum could be averaged between multiple previous takes. Then it could make more sense.

  • @migoga14
    @migoga14 5 лет назад +3

    Hey Mark, Great tutorial.
    I would like to integrate this pyqtgraph graph in a Pyqt5 widget, so that it is executed when pressing a Pushbutton. Somebody could help me? I've tried it in various ways but the program crashes

  • @raysrcsandtech
    @raysrcsandtech 3 года назад

    Could this work on a Raspberry Pi, would the python code be the same? I have a Pi with the sense hat that has an array of LED and want to try and make a 8 bar graph audio spectrum analyzer

  • @rawkstar952
    @rawkstar952 5 лет назад

    great project but can you help me? even if dont talk, the waveform moves. please reply thanks

  • @kaotix9841
    @kaotix9841 3 года назад

    is there additional downloads needed? Ive installed about 10 different libraries and nothing is working at all, Is there meant to be multiple files or is it all in one file? I've tried copying from your git hub and still doesn't work...help?

  • @tiras7700
    @tiras7700 3 года назад

    Excellent tutorials! Though, I've tried all the codes in the github and only the sample ones worked. The others always threw some errors on 'window', 'float number'
    I don't know where I maybe wrong

    • @staalklang
      @staalklang 3 года назад +1

      self.f = np.linspace(0, self.RATE / 2, self.CHUNK // 2)

    • @staalklang
      @staalklang 3 года назад +1

      It expect an integer division not a float division
      hence the double //

  • @hexene6679
    @hexene6679 7 лет назад +1

    Hey! I've been customizing the jupyter notebook version for what i needed and it's working just fine, but now that i'm trying the same code with sublimetext, the program runs but the graph never shows, what could it be?

    • @MarkJay
      @MarkJay  7 лет назад

      Luis Ech are you using the matplotlib version or the pyqtgraph version? For pyqtgraph, you need to download and install the .exe file from pyqtgraph.org.

    • @MarkJay
      @MarkJay  7 лет назад

      here is the matplotlib version that will work in sublime text
      github.com/markjay4k/Audio-Spectrum-Analyzer-in-Python/blob/master/audio_spectrum.py
      and here is the pyqtgraph version that works in sublimetext
      github.com/markjay4k/Audio-Spectrum-Analyzer-in-Python/blob/master/audio_spectrumQT.py

  • @eliassegundo2930
    @eliassegundo2930 7 лет назад

    Thanks!, this tutorials are just what I was looking for, I am trying to get the numerical value of the peak in the spectrum, I find the max value of the spectrum array and then I try to get the index of that max value to get its position on the frequency domain, but that doesn't work correctly, what can be wrong?

    • @MarkJay
      @MarkJay  7 лет назад +1

      Elias Segundo glad you liked it! Theres a number of ways you can get the index from a numpy array, but probably the simplest is to use argmax. Check out the numpy docs here
      docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.argmax.html#numpy.argmax

    • @eliassegundo2930
      @eliassegundo2930 7 лет назад +1

      Thank you very much! I tried to make my own function but I don't know enough about how numpy arrays work , I made it with argmax, for some reason the first value of sp_data is always the max element so I use this : print(self.f[np.argmax(sp_data[1::])]) in update function and it's working, now I can know the numeric frequency.

  • @thelostman5625
    @thelostman5625 3 года назад

    Hi. I want to display Audio Spectrum in my Assistant-Program. And want to make it visually appealing. I want to create circular Spectrum. How can I create something like that?

  • @lngmngx5336
    @lngmngx5336 7 лет назад

    I tried to set the linewidth as you did in the video but it didn't work for me (and the lines in the video don't seem to be 3-pixel wide either), so I added an extra line of code for styling the line:
    self.traces[name] = self.waveform.plot()
    self.traces[name].setPen(color='c', width=2)
    Anyway, thanks for this great tutorial!

    • @MarkJay
      @MarkJay  7 лет назад

      nice, I think I noticed that my linewidth wasnt changing. thanks for the tip

  • @arlenalem
    @arlenalem 6 лет назад +1

    Good video man, Im using the code in order to plot some data, How could i update waveform using external data to the class?

    • @MarkJay
      @MarkJay  6 лет назад

      if you can get the external waveform into python and converted to a numpy array, you can plot it

    • @InarusLynx
      @InarusLynx 6 лет назад

      @@MarkJay say I was trying to get 128 hex numbers from a serial connection and I have them in a list. How would I go about plotting them? I set up the x axis to be 0-127 and y axis to be from 0-0xfff (which is the max number that it can be). Also when I run the command p.animation() (p = Plot2D()) it doesn't plot anything. Is that because the data is a list and not a numpy array? Thank you for your help. My experience with python is about 1 days worth, but I've programmed in C++ and verilog quite a bit. I'll probably try converting the list into a numpy array and see if that fixes things.

  • @realjames1
    @realjames1 4 года назад

    Hi, I don't know if you can still respond, but if I were to use pyaudio to get the volume of my mic, how would I be able to output that as one variable?

  • @marianoarouxet6106
    @marianoarouxet6106 5 лет назад

    Mark Jay thankssss. I used it to starting with python.
    I have added an averge to fft using numpy arrays, using 10averages the spectrum becomes more static but still responds to change in sound.
    I think I've changed some variables names, but:
    Inside __init__ method:
    # Average FFT setup
    self.AVERAGE = 10
    # Number of averages
    self.av_fft_count = 0 # a Counter
    Changes in update()
    def update(self):

    # Gráfico temporal
    wf_data = self.stream.read(self.CHUNK)
    wf_data = struct.unpack(str(2 * self.CHUNK) + 'B', wf_data)
    wf_data = np.array(wf_data, dtype ='b')[::2] + 128
    self.trace(name = 'waveform', dataset_x = self.t, dataset_y = wf_data)

    # Gráfico espectral
    sp_data = fft(np.array(wf_data, dtype = 'int8') - 128)
    sp_data = np.abs(sp_data[0:int(self.CHUNK / 2)]) * 2 / (128 * self.CHUNK)

    # FFT
    average
    if self.av_fft_count == 0: # First spectrum, I define a array using sp_data
    self.sp_data_avg = np.array(sp_data)
    self.av_fft_count += 1

    elif self.av_fft_count < self.AVERAGE: # less than self.AVERAGE spectrums, I add a columns to the array
    self.sp_data_avg = np.vstack([self.sp_data_avg , sp_data])
    self.av_fft_count += 1

    else: # More than self.AVERAGE sepetrums, I delete the first column and add a new one
    self.sp_data_avg = np.vstack([self.sp_data_avg[1:,:] , sp_data])
    self.av_fft_count += 1

    sp_data_av = self.sp_data_avg.sum(axis = 0)
    # Here I make the sum of each row element (the average)


    self.trace(name = 'spectrum', dataset_x = self.f, dataset_y = sp_data_av) # Plotting sp_data_av instead of sp_data

    • @marcosvilleda236
      @marcosvilleda236 4 года назад

      Hola mario, tienes el código completo? Saludos

  •  5 лет назад

    What do You suggest for monitoring square scale from 25 to 4186 Hz. How to modify the code?

    • @scrapolio7885
      @scrapolio7885 5 лет назад

      Jānis Grīnvalds did you find a solution to this?

  • @ashishjain121
    @ashishjain121 6 лет назад

    Sir the code ran successfully but just for a modification how to hide the axes and only look like a real-time spectrum

  • @gittin_funky
    @gittin_funky 3 года назад

    When audio_app = AudioStream() is called I get a TypeError: 'float' object cannot be interpreted as an integer error
    Appears to be caused by line 63 self.f = np.linspace(0, self.RATE / 2, self.CHUNK / 2)
    Any ideas?

    • @streamyourwork9140
      @streamyourwork9140 3 года назад

      solution: self.f = np.linspace(0, self.RATE / 2, self.CHUNK // 2)
      For some reason when you do devide self.CHUNK it bacome float...

  • @sgenovana
    @sgenovana 2 года назад

    hello How can you convert it to spiral and make it thicker? btw nice video😁

  • @NaOuTiX
    @NaOuTiX 7 лет назад +1

    hey,very good prog right here!Thanks a lot for sharing but i have a suggestion! i see that you put a log in the y axis so we don't really see between 0.1 and 1 maybe you should remove it!

    • @MarkJay
      @MarkJay  7 лет назад

      Lucas starfifou glad you liked it! I posted the code to github. Feel free to download and modify however you like

    • @NaOuTiX
      @NaOuTiX 7 лет назад

      Mark Jay yes that works better without log on yaxis, and have you an idea of improve the quality of low frenquencies ?

    • @MarkJay
      @MarkJay  7 лет назад

      Lucas starfifou i think you will need to increase your sample rate. Or maybe you can use a cosine transfer instead of the FFT, but I'm not certain about that.

  • @BhaskarMitrauncc
    @BhaskarMitrauncc 6 лет назад +1

    What is the platform in which you are coding? I mean where are you writing the code

    • @MarkJay
      @MarkJay  6 лет назад

      Bhaskar Mitra I use atom

  • @mr1enrollment
    @mr1enrollment 3 года назад

    why are you still using only 8 bit data?

    • @MarkJay
      @MarkJay  3 года назад

      The bit depth can be increased if needed. But I'm not concerned with the audio quality since I'm not actually playing the audio back. Its just for the graphs

    • @mr1enrollment
      @mr1enrollment 3 года назад

      @@MarkJay nuts

  • @davrik1396
    @davrik1396 5 лет назад

    Thank yoy

  • @jsgaming9839
    @jsgaming9839 4 года назад

    FORMAT = pyaudio.paInt16 # int (16 bits)
    data = upack( str( CHUNK * 2 ) + "B", data ) # byte (8 bits)
    Can somebody explain what the f... Why it works?

  • @KWhite-f5e
    @KWhite-f5e 3 месяца назад

    Jackson Steven Taylor Eric Gonzalez Michelle

  • @JustDux
    @JustDux 3 года назад

    Can you make a spectrogram like in this video:
    ruclips.net/video/AqqaYs7LjlM/видео.html
    ?

  • @francisneequaye3134
    @francisneequaye3134 4 года назад

    DUDE. include your Git hub. Expecting novices to follow along with voice alone is VERY vain and YOU KNOW , the slowest method in teaching code, but hey, makes you sound smart I guess.