Converting a Python code to Matlab script

Viewed 232

I have been working on an assignment on musical note analysis and I have the Python code for it. However, I am required to convert it to Matlab, and I have come across some issues here. I have not attempted something of the sort before.

The Python Code:

import numpy as np
import wave
import struct

def find_nearest(array,value):
    idx = (np.abs(array-value)).argmin()
    return array[idx]


window_size = 2205    
beta = 1   
max_notes = 100    
sampling_freq = 44100
threshold = 600
array = [1046.50, 1174.66, 1318.51, 1396.91, 1567.98, 1760.00, 1975.53,
         2093.00, 2349.32, 2637.02, 2793.83, 3135.96, 3520.00, 3951.07,
         4186.01, 4698.63, 5274.04, 5587.65, 6271.93, 7040.00, 7902.13]

notes = ['C6', 'D6', 'E6', 'F6', 'G6', 'A6', 'B6',
         'C7', 'D7', 'E7', 'F7', 'G7', 'A7', 'B7',
         'C8', 'D8', 'E8', 'F8', 'G8', 'A8', 'B8']
Identified_Notes = []

print ('\n\nReading Audio File...')

sound_file = wave.open(r'C://Audio_Analysis.wav', 'r')
file_length = sound_file.getnframes()


sound = np.zeros(file_length)
mean_square = []
sound_square = np.zeros(file_length)
for i in range(file_length):
    data = sound_file.readframes(1)
    data = struct.unpack("<h", data)
    sound[i] = int(data[0])
    
sound = np.divide(sound, float(2**15)) # Normalize data in range -1 to 1
print(sound)

sound_square = np.square(sound)
frequency = []
dft = []
i = 0
j = 0
k = 0
print(len(sound_square)-window_size)

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.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("frequencies:")   

for i in frequency :
    print(i)
    idx = (np.abs(array-i)).argmin()
    Identified_Notes.append(notes[idx])
print(Identified_Notes)

The Python Code does work by the way.

My attempt at converting it to Matlab Code:

window_size = 2205;
beta = 1;
max_notes = 100;
sampling_freq = 44100;
threshold = 600;
array = py.list({py.list([1046.50,1174.66,1318.51,1396.91,1567.98,1760.00,1975.53]),py.list([2093.00,2349.32,2637.02,2793.83,3135.96,3520.00,2951.07]),py.list([4186.01,4698.63,5274.04,5587.65,6271.93,7040.00,7902.13])});
notes = py.list({py.list(['C6','D6','E6','F6','G6','A6','B6']),py.list(['C7','D7','E7','F7','G7','A7','B7']),py.list(['C8','D8','E8','F8','G8','A8','B8'])});
Identified_Notes = py.list();

fprintf('\n\nReading Audio File...')
sound_file = py.wave.open("C://Audio_Analysis.wav",'r');
file_length = sound_file.getnframes();

sound = py.numpy.zeros(file_length);
mean_square = py.list();
sound_square = py.numpy.zeros(file_length);
for i = file_length
    data = py.wave.sound_file.readframes(1);
    data = py.struct.unpack("<h",data);
    sound(i) = int32(data(0));
end

sound = py.numpy.divide(sound,double(2^15));
py.print(sound)

sound_square = py.numpy.square(sound);
frequency = py.list();
dft = py.list();
i = 0;
j = 0;
k = 0;
fprintf(py.len(sound_square)-window_size)

while i <= (py.len(sound_square)-window_size)
    s = 0.0;
    j = 0;

    while j <= window_size
        s = s + sound_square(i+j);
        j = j + 1;
    end
    
    if s < threshold
        
        if (i-k) > window_size*4
            dft = py.numpy.array(dft);
            dft = py.numpy.fft.fft(sound(k:i));
            dft = py.numpy.argsort(dft);
            
            df = cellfun(@char,cell(dft),'UniformOutput',false)
            
            if (df(0) > df(-1) && df(1) > df(-1))
                i_max = df(-1);
            
            elseif (df(1) > df(0) && df(-1) > df(0))
                i_max = df(0);
               
            else 
                i_max = dft(1);
            
            end
            
            frequency.append((i_max*sampling_freq)/(i-k));
            dft.clear();
            k = i + 1;
        end
    end
    i = i + window_size;
end
    
py.print("length:",py.len(frequency))
fprintf('frequencies:')

for i = frequency
    py.print(i)
    idx = min(py.numpy.abs(array-i));
    Identified_Notes.append(notes(idx));
end
py.print(Identified_Notes)

function y = find_nearest(array,value)
    idx = min(py.numpy.abs(array-value));
end

I've read some Matlab documentation to try this out, but I am quite clueless here. I get the following errors, though there may be more:

enter image description here

How do I go from here?

0 Answers
Related