-2

I'm giving my code with few audio files which are not giving appropriate output. Code:

import numpy as np
import math
import wave
import os
import struct

def note_detect(audio_file):

    Detected_Note = ""

    beta = 1   
    max_notes = 100   
    sampling_freq = 38050 
    window_size = (sampling_freq / 37)   
    threshold = 600
    array = [440.00, 130.8, 329.6, 196]

    notes = ['A4', 'C3', 'E4', 'G3' ]
    Identified_Notes = []
    file_length = audio_file.getnframes()
    sound = np.zeros(file_length)
    for i in range(file_length):
        data = audio_file.readframes(1)
        data = struct.unpack("<h", data)
        sound[i] = int(data[0])
    sound = np.divide(sound, float(2**15))

    sound_square = np.square(sound)
    frequency = []
    dft = []
    i = 0
    j = 0
    k = 0
    while(i<=len(sound_square)-window_size):
        s = 0.0
        j = 0
        while(j<=window_size):
            s = s + sound_square[i+j]
            j = j + 1
        if s < threshold:
            if(i-k>window_size*4):
                dft = np.array(dft)
                dft = np.fft(sound[k:i])

                dft=np.argsort(dft)

                if(dft[0]>dft[-1] and dft[1]>dft[-1]):
                    i_max = dft[-1]
                elif(dft[1]>dft[0] and dft[-1]>dft[0]):
                    i_max = dft[0]
                else :
                    i_max = dft[1]

                frequency.append((i_max*sampling_freq)/(i-k))
                dft = []
                k = i+1
        i = i + window_size

    print('length',len(frequency))
    print("frequency")

    for i in frequency :
        print(i)
        idx = (np.abs(array-i)).argmin()
        Identified_Notes.append(notes[idx])
    print(Identified_Notes)
    Detected_Note=max(Identified_Notes,key=Identified_Notes.count)      
    return Detected_Note



if __name__ == "__main__":


    path = os.getcwd()

    file_name = path + "\Task_1.1_Audio_files\Audio_4.wav"
    audio_file = wave.open(file_name)

    Detected_Note = note_detect(audio_file)

    print("\n\tDetected Note = " + str(Detected_Note))


    x = raw_input("\n\tWant to check output for all Audio Files - Y/N: ")

    if x == 'Y':

        Detected_Note_list = []

        file_count = len(os.listdir(path + "\Task_1.1_Audio_files"))

        for file_number in range(1, file_count):

            file_name = path + "\Task_1.1_Audio_files\Audio_"+str(file_number)+".wav"
            audio_file = wave.open(file_name)

            Detected_Note = note_detect(audio_file)

            Detected_Note_list.append(Detected_Note)

        print("\n\tDetected Notes = " + str(Detected_Note_list))

Audio files link: https://drive.google.com/open?id=1KVEQQUqBvwgDPf2JC_uQ0L6M_gzGDG6l

Respective output for Audio_6.wav is A4, for Audio_4.wav is E4,for Audio_5.wav is G3

Scott Stensland
  • 26,870
  • 12
  • 93
  • 104
jarvis
  • 1
  • 1
  • 2
  • Hi, and welcome to SO. Please take a look at the [Help centre](https://stackoverflow.com/help/how-to-ask). In particular, please include the code in the post and explain your question. What is "appropriate output"? How is it different from what you get? No one knows, except for you. – Norrius Nov 14 '18 at 11:31
  • Welcome to SO ;) Please read this article on [how to ask a good question](https://stackoverflow.com/help/how-to-ask). This would include a proper description of what you are trying to achieve, your code (or the relevant snippets) as well as your efforts showing what you have tried so far and possible error messages. – iLuvLogix Nov 14 '18 at 11:32
  • I've uploaded code as per you suggested. – jarvis Nov 14 '18 at 12:21

1 Answers1

0

it's probably because you're using a custom rectangular window, try blackmanharris from scipy.signal and use np.argmax for calculating i_max. I checked the audio files and they only have 1 frequency but you're calculating 4 from your algorithm and then taking the highest one. I've adjusted the code take a look but the Audio_4.wav file is still showing the note E5 on my side that is probably the note you gave could be wrong, can you get it checked?

def matching_freq(freq):
    note=""
    if(freq>15 and freq<17.32):
        note= "C0"
        return note
    elif(freq>17.32 and freq<19.45):
        note="D0"
        return note
    elif(freq>19.45 and freq<20.8):
        note="E0"
        return note
    elif(freq>20.8 and freq<23.12):
        note="F0"
        return note
    elif(freq>23.12 and freq<25.96):
        note="G0"
        return note
    elif(freq>25.96 and freq<29.14):
        note="A0"
        return note
    elif(freq>29.14 and freq<31):
        note="B0"
        return note
    elif(freq>31 and freq<34.65):
        note="C1"
        return note
    elif(freq>34.65 and freq<38.89):
        note="D1"
        return note
    elif(freq>38.89 and freq<42):
        note="E1"
        return note
    elif(freq>42 and freq<46.25):
        note="F1"
        return note
    elif(freq>46.25 and freq<51.91):
        note="G1"
        return note
    elif(freq>51.91 and freq<58.27):
        note="A1"
        return note
    elif(freq>58.27 and freq<63):
        note="B1"
        return note
    elif(freq>63 and freq<69.30):
        note="C2"
        return note
    elif(freq>69.30 and freq<77.78):
        note="D2"
        return note
    elif(freq>77.78 and freq<85):
        note="E2"
        return note
    elif(freq>85 and freq<92.50):
        note="F2"
        return note
    elif(freq>92.50 and freq<103.83):
        note="G2"
        return note
    elif(freq>103.83 and freq<116.54):
        note="A2"
        return note
    elif(freq>116.54 and freq<126):
        note="B2"
        return note
    elif(freq>126 and freq<138.59):
        note="C3"
        return note
    elif(freq>138.59 and freq<155.56):
        note="D3"
        return note
    elif(freq>155.56 and freq<168):
        note="E3"
        return note
    elif(freq>168 and freq<185):
        note="F3"
        return note
    elif(freq>185 and freq<207.65):
        note="G3"
        return note
    elif(freq>207.65 and freq<233.08):
        note="A3"
        return note
    elif(freq>233.08 and freq<253):
        note="B3"
        return note
    elif(freq>253 and freq<277.18):
        note="C4"
        return note
    elif(freq>277.18 and freq<311.13):
        note="D4"
        return note
    elif(freq>311.13 and freq<338):
        note="E4"
        return note
    elif(freq>338 and freq<369.99):
        note="F4"
        return note
    elif(freq>369.99 and freq<415.3):
        note="G4"
        return note
    elif(freq>415.3 and freq<466.16):
        note="A4"
        return note
    elif(freq>466.16 and freq<500):
        note="B4"
        return note
    elif(freq>500 and freq<554.37):
        note="C5"
        return note
    elif(freq>554.37 and freq<622.25):
        note="D5"
        return note
    elif(freq>622.25 and freq<675):
        note="E5"
        return note
    elif(freq>675 and freq<740):
        note="F5"
        return note
    elif(freq>740 and freq<830):
        note="G5"
        return note
    elif(freq>830 and freq<932):
        note="A5"
        return note
    elif(freq>932 and freq<1000):
        note="B5"
        return note
    elif(freq>1000 and freq<1108):
        note="C6"
        return note
    elif(freq>1108 and freq<1244):
        note="D6"
        return note
    elif(freq>1244 and freq<1350):
        note="E6"
        return note
    elif(freq>1350 and freq<1480):
        note="F6"
        return note
    elif(freq>1480 and freq<1661.22):
        note="G6"
        return note
    elif(freq>1661.22 and freq<1864):
        note="A6"
        return note
    elif(freq>1864 and freq<2000):
        note="B6"
        return note
    elif(freq>2000 and freq<2217.46):
        note="C7"
        return note
    elif(freq>2217.46 and freq<2489.02):
        note="D7"
        return note
    elif(freq>2489.02 and freq<2700):
        note="E7"
        return note
    elif(freq>2700 and freq<2960):
        note="F7"
        return note
    elif(freq>2960 and freq<3322.4):
        note="G7"
        return note
    elif(freq>3322.4 and freq<3729):
        note="A7"
        return note
    elif(freq>3729.31 and freq<4040):
        note="B7"
        return note
    elif(freq>4040 and freq<4435):
        note="C8"
        return note
    elif(freq>4435 and freq<4978):
        note="D8"
        return note
    elif(freq>4978 and freq<5350):
        note="E8"
        return note
    elif(freq>5350 and freq<5919):
        note="F8"
        return note
    elif(freq>5919 and freq<6644):
        note="G8"
        return note
    elif(freq>6644 and freq<7458):
        note="A8"
        return note
    elif(freq>7458 and freq<8000):
        note="B8"
        return note


def note_detect(audio_file):
Detected_Note = []
length = audio_file.getnframes()
sound  = np.zeros(length)

for i in range(length):
    data = audio_file.readframes(1)
    data = struct.unpack("<h", data)
    sound[i] = int(data[0])

sound = np.divide(sound, float(2**15))
window = sound * np.blackmanharris(len(sound))
f = np.fft.fft(window)
i_max = np.argmax(abs(f))
print(i_max)
freq = (i_max * fs)/len(sound)
print(freq)
Detected_Note = matching_freq(freq)
return Detected_Note`
  • I've checked all audio files in audacity and they are giving appropriate output as given in my query. I've gone through your code and added one more audio file in drive named as Audio_2.wav which has note A4 and through your code I'm getting E7. – jarvis Dec 09 '18 at 06:15