将Python代码转换为Matlab脚本

2024-04-29 17:18:36 发布

您现在位置:Python中文网/ 问答频道 /正文

我一直在做一个关于音符分析的作业,我有它的Python代码。但是,我需要将其转换为Matlab,我在这里遇到了一些问题。我以前从未尝试过这样的事情

Python代码:

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)

顺便说一句,Python代码确实有效

我尝试将其转换为Matlab代码:

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

我已经阅读了一些Matlab文档来尝试这一点,但我在这里完全不懂。我发现以下错误,但可能还有更多错误:

enter image description here

我该怎么走


Tags: pynumpydfsizenpwindowarraylength