Frequency Reader? mekha Programmer named Tim Posts: 18 Threads: 3 Joined: Jul 2018 Reputation: Jul-02-2018, 12:11 PM (This post was last modified: Jul-07-2018, 08:34 AM by Larz60+.) a sound is played in real time then in the window resulting a frequency number 188.000 Hz, 220.000 Hz, etc and keep goes on while the sound is still played and keep resulting the numbers... I also wanted to made a marker on some frequency for the range like : A = 440.000 Hz G = 120.000 Hz D = 250.000 Hz E = 550.000 Hz etc I've found a discussion that almost similar with this project I wanted to create, they put the coding like this ```import pyaudio import os import struct import numpy as np import matplotlib.pyplot as plt import time from time import sleep %matplotlib tk CHUNK = 2**14 #2**15 #4096 WIDTH = 2 FORMAT = pyaudio.paInt16 CHANNELS = 2 RATE = 44100 dt = 1.0/RATE ### frequencies of the strings for the violin (tunned in A), in Hz f4 = 195.998 ## G3 f3 = 293.665 ## D4 f2 = 440.000 ## A4 f1 = 659.255 ## E5 n = CHUNK freqs = np.fft.rfftfreq(n, d = dt) def Frequency_of_position(position): """ Returns the frequency (Hz) of the note in from its position (halftones) relative to A4 in an equal tempered scale. Ex: 0 -> 440 Hz (A4), 12 -> 880 Hz (A5).""" return 440.0*(2**(1.0/12.0))**position def Position_to_note(position): "A A# B C C# D D# E F F# G G#" SCALE = ["A", "A#", "B", "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#"] LETTER = SCALE[position % 12] NUMBER = str(int((position+57) / 12)) return LETTER+NUMBER pos = np.array(range(-36,48)) vnote_freqs = np.vectorize(Frequency_of_position) note_freqs = vnote_freqs(pos) def get_frequency( spectrum ): return freqs[np.argmax(spectrum)] class Freq_analysis(object): def __init__(self): self.pa = pyaudio.PyAudio() self.stream = self.open_mic_stream() self.plots = self.prepare_figure() #self.fig_and_axes = self.prepare_figure() #self.first_plot = self.plot_first_figure() def stop(self): self.stream.close() def open_mic_stream( self ): device_index = self.find_input_device() stream = self.pa.open( format = FORMAT, channels = CHANNELS, rate = RATE, input = True, input_device_index = device_index, frames_per_buffer = CHUNK) return stream def find_input_device(self): device_index = None for i in range( self.pa.get_device_count() ): devinfo = self.pa.get_device_info_by_index(i) print( "Device %d: %s"%(i,devinfo["name"]) ) for keyword in ["mic","input"]: if keyword in devinfo["name"].lower(): print( "Found an input: device %d - %s"% (i,devinfo["name"]) ) device_index = i return device_index if device_index == None: print( "No preferred input found; using default input device." ) return device_index def prepare_figure(self): plt.ion() fig1 = plt.figure(1, figsize = (16,6)) wide_plot = plt.subplot(2,1,1) plt.vlines([f1,f2,f3,f4],1,1e17, linestyles = 'dashed') plt.xlabel("freq (Hz)") plt.ylabel("S^2 (u. arb.)") plt.xscale('log') plt.yscale('log') plt.xlim([80,4000]) #plt.xlim([600,700]) #plt.xlim([400,500]) plt.ylim([1e0,1e17]) spec_w, = plt.plot([1,1],[1,1], '-',c = 'blue') f4_plot = plt.subplot(2,4,5) plt.vlines(f4,1,1e17, linestyles = 'dashed') plt.xlabel("freq (Hz)") plt.ylabel("S^2 (u. arb.)") plt.yscale('log') plt.xlim([140,260]) plt.ylim([1e0,1e17]) spec_f4, = plt.plot([1,1],[1,1], '-',c = 'blue') f3_plot = plt.subplot(2,4,6) plt.vlines(f3,1,1e17, linestyles = 'dashed') plt.xlabel("freq (Hz)") plt.yscale('log') plt.xlim([220,380]) plt.ylim([1e0,1e17]) spec_f3, = plt.plot([1,1],[1,1], '-',c = 'blue') f2_plot = plt.subplot(2,4,7) plt.vlines(f2,1,1e17, linestyles = 'dashed') plt.xlabel("freq (Hz)") plt.yscale('log') plt.xlim([400,500]) plt.ylim([1e0,1e17]) spec_f2, = plt.plot([1,1],[1,1], '-',c = 'blue') f1_plot = plt.subplot(2,4,8) plt.vlines(f1,1,1e17, linestyles = 'dashed') plt.xlabel("freq (Hz)") plt.yscale('log') plt.xlim([600,700]) plt.ylim([1e0,1e17]) spec_f1, = plt.plot([1,1],[1,1], '-',c = 'blue') plt.draw() #return fig1, wide_plot, f1_plot, f2_plot, f3_plot, f4_plot return spec_w, spec_f1, spec_f2, spec_f3, spec_f4 def PrintFreq(self, S2): dominant = get_frequency( S2 ) dist = np.abs(note_freqs-dominant) closest_pos = pos[np.argmin(dist)] closest_note = Position_to_note(closest_pos) print(dominant, "(",closest_note, "=",Frequency_of_position(closest_pos),")") def listen(self): try: block = self.stream.read(CHUNK) except IOError: # An error occurred. print( "Error recording.") return indata = np.array(struct.unpack("%dh"%(len(block)/2),block)) n = indata.size freqs = np.fft.rfftfreq(n, d = dt) data_rfft = np.fft.rfft(indata) S2 = np.abs(data_rfft)**2 #self.PrintFreq(block) #self.update_fig(block) self.PrintFreq(S2) self.update_fig(freqs, S2) def update_fig(self, freqs, S2): self.plots[0].set_xdata(freqs) self.plots[1].set_xdata(freqs) self.plots[2].set_xdata(freqs) self.plots[3].set_xdata(freqs) self.plots[4].set_xdata(freqs) self.plots[0].set_ydata(S2) self.plots[1].set_ydata(S2) self.plots[2].set_ydata(S2) self.plots[3].set_ydata(S2) self.plots[4].set_ydata(S2) plt.draw() plt.pause(0.001) if __name__ == "__main__": Tuner = Freq_analysis() for i in range(100): Tuner.listen() plt.ioff() plt.show()```when I run the the result got me confused... ``````Output:Device 0: Microsoft Sound Mapper - Input Found an input: device 0 - Microsoft Sound Mapper - Input 4635.02197266 ( D8 = 4698.63628668 ) 21.533203125 ( A1 = 55.0 ) 32.2998046875 ( A1 = 55.0 ) 61.9079589844 ( B1 = 61.735412657 ) 26.9165039063 ( A1 = 55.0 ) 29.6081542969 ( A1 = 55.0 ) 34.9914550781 ( A1 = 55.0 ) 18.8415527344 ( A1 = 55.0 ) 18.8415527344 ( A1 = 55.0 ) 18.8415527344 ( A1 = 55.0 ) 29.6081542969 ( A1 = 55.0 ) 18.8415527344 ( A1 = 55.0 ) 88.8244628906 ( F2 = 87.3070578583 ) 53.8330078125 ( A1 = 55.0 ) 80.7495117188 ( E2 = 82.4068892282 ) 80.7495117188 ( E2 = 82.4068892282 ) 40.3747558594 ( A1 = 55.0 ) 40.3747558594 ( A1 = 55.0 ) 43.06640625 ( A1 = 55.0 ) 86.1328125 ( F2 = 87.3070578583 ) 43.06640625 ( A1 = 55.0 ) 91.5161132813 ( F#2 = 92.4986056779 ) 45.7580566406 ( A1 = 55.0 ) 45.7580566406 ( A1 = 55.0 ) 45.7580566406 ( A1 = 55.0 ) 45.7580566406 ( A1 = 55.0 ) 48.4497070313 ( A1 = 55.0 ) 45.7580566406 ( A1 = 55.0 ) 45.7580566406 ( A1 = 55.0 ) 45.7580566406 ( A1 = 55.0 ) 48.4497070313 ( A1 = 55.0 ) 48.4497070313 ( A1 = 55.0 ) 45.7580566406 ( A1 = 55.0 ) 43.06640625 ( A1 = 55.0 ) 43.06640625 ( A1 = 55.0 ) 48.4497070313 ( A1 = 55.0 ) 51.1413574219 ( A1 = 55.0 ) 16.1499023438 ( A1 = 55.0 ) 13.4582519531 ( A1 = 55.0 ) 16.1499023438 ( A1 = 55.0 ) 53.8330078125 ( A1 = 55.0 ) 40.3747558594 ( A1 = 55.0 ) 45.7580566406 ( A1 = 55.0 ) 32.2998046875 ( A1 = 55.0 ) 169.573974609 ( E3 = 164.813778456 ) 53.8330078125 ( A1 = 55.0 ) 40.3747558594 ( A1 = 55.0 ) 26.9165039063 ( A1 = 55.0 ) 29.6081542969 ( A1 = 55.0 ) 32.2998046875 ( A1 = 55.0 ) 26.9165039063 ( A1 = 55.0 ) 32.2998046875 ( A1 = 55.0 ) 29.6081542969 ( A1 = 55.0 ) 45.7580566406 ( A1 = 55.0 ) 45.7580566406 ( A1 = 55.0 ) 48.4497070313 ( A1 = 55.0 ) 48.4497070313 ( A1 = 55.0 ) 48.4497070313 ( A1 = 55.0 ) 45.7580566406 ( A1 = 55.0 ) 48.4497070313 ( A1 = 55.0 ) 56.5246582031 ( A1 = 55.0 ) 56.5246582031 ( A1 = 55.0 ) 56.5246582031 ( A1 = 55.0 ) 48.4497070313 ( A1 = 55.0 ) 113.049316406 ( A2 = 110.0 ) 142.657470703 ( C#3 = 138.591315488 ) 139.965820313 ( C#3 = 138.591315488 ) 67.2912597656 ( C2 = 65.4063913251 ) 69.9829101563 ( C#2 = 69.2956577442 ) 75.3662109375 ( D2 = 73.4161919794 ) 45.7580566406 ( A1 = 55.0 ) 142.657470703 ( C#3 = 138.591315488 ) 45.7580566406 ( A1 = 55.0 ) 45.7580566406 ( A1 = 55.0 ) 113.049316406 ( A2 = 110.0 ) 113.049316406 ( A2 = 110.0 ) 51.1413574219 ( A1 = 55.0 ) 51.1413574219 ( A1 = 55.0 ) 48.4497070313 ( A1 = 55.0 ) 51.1413574219 ( A1 = 55.0 ) 53.8330078125 ( A1 = 55.0 ) 48.4497070313 ( A1 = 55.0 ) 45.7580566406 ( A1 = 55.0 ) 32.2998046875 ( A1 = 55.0 ) 29.6081542969 ( A1 = 55.0 ) 64.599609375 ( C2 = 65.4063913251 ) 18.8415527344 ( A1 = 55.0 ) 45.7580566406 ( A1 = 55.0 ) 40.3747558594 ( A1 = 55.0 ) 32.2998046875 ( A1 = 55.0 ) 34.9914550781 ( A1 = 55.0 ) 67.2912597656 ( C2 = 65.4063913251 ) 40.3747558594 ( A1 = 55.0 ) 80.7495117188 ( E2 = 82.4068892282 ) 24.2248535156 ( A1 = 55.0 ) 32.2998046875 ( A1 = 55.0 ) 24.2248535156 ( A1 = 55.0 ) 43.06640625 ( A1 = 55.0 ) 37.6831054688 ( A1 = 55.0 ) 16.1499023438 ( A1 = 55.0 )``````STOPPED after that.... what I wanted is something more simple than this kind, like audio frequency analysis (perhaps...?) Thank you in advance! Reply Posts: 7,816 Threads: 145 Joined: Sep 2016 Reputation: Jul-02-2018, 12:22 PM what exactly is your question? If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein How to Ask Questions The Smart Way: link and another link Create MCV example Debug small programs Reply mekha Programmer named Tim Posts: 18 Threads: 3 Joined: Jul 2018 Reputation: Jul-02-2018, 12:26 PM (Jul-02-2018, 12:22 PM)buran Wrote: what exactly is your question? a real time sound frequency reader? sorry if I being not clear Reply Posts: 7,816 Threads: 145 Joined: Sep 2016 Reputation: Jul-02-2018, 12:30 PM Unfortunately, this is not how the forum works. We are not going to do it for you. It looks like you have found a code that is a good starting point and in fact is doing more than what you want. Put some efforts to change it and get the desired results. Ask specific questions when you have a specific problem If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein How to Ask Questions The Smart Way: link and another link Create MCV example Debug small programs Reply mekha Programmer named Tim Posts: 18 Threads: 3 Joined: Jul 2018 Reputation: Jul-02-2018, 12:38 PM (This post was last modified: Jul-02-2018, 12:48 PM by mekha.) (Jul-02-2018, 12:30 PM)buran Wrote: Unfortunately, this is not how the forum works. We are not going to do it for you. It looks like you have found a code that is a good starting point and in fact is doing more than what you want. Put some efforts to change it and get the desired results. Ask specific questions when you have a specific problem thank you for your pointer, and once again I'm so sorry if I being so selfish asking more than what it should've been... and I'm so glad you warning me, thank you! I'll be working on it now, got confused because I'm still new to this kind of programming of sound analyzer but I'll try to do it 1st and find an errors that more caused problem and ask more in efficient way (Jul-02-2018, 12:30 PM)buran Wrote: Unfortunately, this is not how the forum works. We are not going to do it for you. It looks like you have found a code that is a good starting point and in fact is doing more than what you want. Put some efforts to change it and get the desired results. Ask specific questions when you have a specific problem But can I ask you like this, why when I run it through Jupyter the result of the data stopped there then it showing some data graphics? (not testing thorough yet other than Jupyter) Reply mekha Programmer named Tim Posts: 18 Threads: 3 Joined: Jul 2018 Reputation: Jul-06-2018, 02:53 AM Got my answer, the answer is this : https://pypi.org/project/frequency_analyzer/#files Reply DeaD_EyE Da Bishop Posts: 1,885 Threads: 8 Joined: May 2017 Reputation: Jul-06-2018, 08:29 AM (This post was last modified: Jul-06-2018, 08:30 AM by DeaD_EyE.) I gave already the answer in another thread: https://python-forum.io/Thread-PyQt-Assi...8#pid51618 I'm using itertools.product to simplify the iteration. ```# without itertools.product for band in range(-1, 3): for note in ('A','B','C'): print(band, note) # same with itertools.product import itertools bands = range(-1, 3) notes = ('A','B','C') for band, note in itertools.product(bands, notes): print(band, note)```The rest is math and string concatenation or interpolation. There are also different ways to calculate the frequencies. I have use the midi number, which uses another formula, as your example. Just using a ready made module may help you with your current task, but it won't help you to understand Python and the algorithm. BTW: I'm not sure if I name the things right: Bands, Octaves, Notes Almost dead, but too lazy to die: https://sourceserver.info All humans together. We don't need politicians! Reply mekha Programmer named Tim Posts: 18 Threads: 3 Joined: Jul 2018 Reputation: Jul-07-2018, 02:28 AM (This post was last modified: Jul-07-2018, 02:28 AM by mekha.) (Jul-06-2018, 08:29 AM)DeaD_EyE Wrote: I gave already the answer in another thread: https://python-forum.io/Thread-PyQt-Assi...8#pid51618 I'm using itertools.product to simplify the iteration. ```# without itertools.product for band in range(-1, 3): for note in ('A','B','C'): print(band, note) # same with itertools.product import itertools bands = range(-1, 3) notes = ('A','B','C') for band, note in itertools.product(bands, notes): print(band, note)```The rest is math and string concatenation or interpolation. There are also different ways to calculate the frequencies. I have use the midi number, which uses another formula, as your example. Just using a ready made module may help you with your current task, but it won't help you to understand Python and the algorithm. BTW: I'm not sure if I name the things right: Bands, Octaves, Notes This one is a bit different with the other of my post though its also need the same thing, but yes the major is analyzer itself... But thank you very much, I'm truly appreciate all of your help and it does help me understanding a bit of how analyzer works too. And I have a question, what's this itertools do? when I test run the both code you posted with and without itertools, they gave the same result (Jul-06-2018, 08:29 AM)DeaD_EyE Wrote: I gave already the answer in another thread: https://python-forum.io/Thread-PyQt-Assi...8#pid51618 I'm using itertools.product to simplify the iteration. ```# without itertools.product for band in range(-1, 3): for note in ('A','B','C'): print(band, note) # same with itertools.product import itertools bands = range(-1, 3) notes = ('A','B','C') for band, note in itertools.product(bands, notes): print(band, note)```The rest is math and string concatenation or interpolation. There are also different ways to calculate the frequencies. I have use the midi number, which uses another formula, as your example. Just using a ready made module may help you with your current task, but it won't help you to understand Python and the algorithm. BTW: I'm not sure if I name the things right: Bands, Octaves, Notes oh yes I do also have another very confusing result that is when I run the code that I posted here it always stopped before I terminate them, so when I force close it'll say do I want to terminate them while the program still running... but the thing is the code not even give me any more results, it stopped so suddenly and even if I waited for some minutes, still no updates from before Reply mekha Programmer named Tim Posts: 18 Threads: 3 Joined: Jul 2018 Reputation: Jul-11-2018, 04:04 AM (This post was last modified: Jul-11-2018, 04:04 AM by mekha.) I've cut the codes to simple it without the matplotlib running too, but still it's not make sense why it's always stopping in the middle of the process. And if I terminated the running file's it said if I want to close while it still running... but actually nothing happening at all no update of the data or whatsoever here is the updated code without the matplotlib ```import pyaudio import os import struct import numpy as np import time from time import sleep CHUNK = 2**14 #2**15 #4096 WIDTH = 2 FORMAT = pyaudio.paInt16 CHANNELS = 2 RATE = 44100 dt = 1.0/RATE ### frequencies of the strings for the violin (tunned in A), in Hz f4 = 195.998 ## G3 f3 = 293.665 ## D4 f2 = 440.000 ## A4 f1 = 659.255 ## E5 n = CHUNK freqs = np.fft.rfftfreq(n, d = dt) def Frequency_of_position(position): """ Returns the frequency (Hz) of the note in from its position (halftones) relative to A4 in an equal tempered scale. Ex: 0 -> 440 Hz (A4), 12 -> 880 Hz (A5).""" return 440.0*(2**(1.0/12.0))**position def Position_to_note(position): "A A# B C C# D D# E F F# G G#" SCALE = ["A", "A#", "B", "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#"] LETTER = SCALE[position % 12] NUMBER = str(int((position+57) / 12)) return LETTER+NUMBER pos = np.array(range(-36,48)) vnote_freqs = np.vectorize(Frequency_of_position) note_freqs = vnote_freqs(pos) def get_frequency( spectrum ): return freqs[np.argmax(spectrum)] class Freq_analysis(object): def __init__(self): self.pa = pyaudio.PyAudio() self.stream = self.open_mic_stream() def stop(self): self.stream.close() def open_mic_stream( self ): device_index = self.find_input_device() stream = self.pa.open( format = FORMAT, channels = CHANNELS, rate = RATE, input = True, input_device_index = device_index, frames_per_buffer = CHUNK) return stream def find_input_device(self): device_index = None for i in range( self.pa.get_device_count() ): devinfo = self.pa.get_device_info_by_index(i) print( "Device %d: %s"%(i,devinfo["name"]) ) for keyword in ["mic","input"]: if keyword in devinfo["name"].lower(): print( "Found an input: device %d - %s"% (i,devinfo["name"]) ) device_index = i return device_index if device_index == None: print( "No preferred input found; using default input device." ) return device_index def PrintFreq(self, S2): dominant = get_frequency( S2 ) dist = np.abs(note_freqs-dominant) closest_pos = pos[np.argmin(dist)] closest_note = Position_to_note(closest_pos) print(dominant, "(",closest_note, "=",Frequency_of_position(closest_pos),")") def listen(self): try: block = self.stream.read(CHUNK) except IOError: # An error occurred. print( "Error recording.") return indata = np.array(struct.unpack("%dh"%(len(block)/2),block)) n = indata.size freqs = np.fft.rfftfreq(n, d = dt) data_rfft = np.fft.rfft(indata) S2 = np.abs(data_rfft)**2 #self.PrintFreq(block) #self.update_fig(block) self.PrintFreq(S2) if __name__ == "__main__": Tuner = Freq_analysis() for i in range(100): Tuner.listen()``` Reply