2017-08-18 7 views
1

Le problème que j'ai est un tableau trop grand dans Matlab. Les données du tableau proviennent du fichier audio. Je veux obtenir la réponse impulsionnelle.Array trop grand pour la division dans matlab mais pas python

J'ai d'abord FFT l'original et l'audio enregistré. Puis la division de enregistré par original. Enfin FFT inverse pour obtenir la réponse impulsionnelle. C'était ce que j'avais prévu de faire, mais je me suis retrouvé coincé dans la division.

Coincé en utilisant Matlab, j'ai trouvé un python code qui peut le faire très bien. Je réécris le code dans Matlab et le problème est de retour. Le code est incomplet mais il suffit de montrer le problème.

Espérons obtenir beaucoup de conseils et de critiques. Merci

prévu de faire, mais a échoué si ému sur le prochain code

[y_sweep,Fs] = audioread('sweep.wav'); 
[y_rec,Fs] = audioread('edit_rec_sweep_laptop_1.2.wav'); 
fft_y1 = abs(fft(y_rec(:,1))); 
fft_y2 = abs(fft(y_rec(:,2))); 
fft_x = abs(fft(y_sweep)); 
fft_h1 = fft_y1/fft_x; 
% fft_h2 = fft_y2/fft_x; 
% fft_h = [fft_h1,fft_h2]; 
% h1 = ifft(fft1_h); 

code 'Traduit' de python, mais toujours pas ainsi venu ici

[a,fs] = audioread('sweep.wav'); % sweep 
[b,fs] = audioread('rec.wav'); % rec 

a = pad(a,fs*50,fs*10); 
b = pad(b,fs*50,fs*10); 
[m,n] = size(b); 
h = zeros(m,n); 

for chan = 1:2 
    b1 = b(:,1); 
    ffta = abs(fft(a)); 
    fftb = abs(fft(b1)); 
    ffth = fftb/ffta; 
end 

pad . m fonction (traduit de python mais devrait être correct)

function y = pad(data, t_full, t_pre) 
[row_dim,col_dim] = size(data); 
t_post = t_full - row_dim - t_pre; 
if t_post > 0 
    if col_dim == 1 
     y = [zeros(t_pre,1);data;zeros(t_post,1)]; 
%   width = [t_pre,t_post]; 
    else 
     y1 = [zeros(t_pre,1);data(:,1);zeros(t_post,1)]; 
     y2 = [zeros(t_pre,1);data(:,2);zeros(t_post,1)]; 
     y = [y1,y2]; 
%   width = [[t_pre,t_post],[0,0]]; 
    end 
else 
    if col_dim == 1 
     y = [zeros(t_pre,1);data(t_full - t_pre:end,1)]; 
%   width = [t_pre,0]; 
    else 
     y = [zeros(t_pre,1);data(t_full - t_pre:end,1)]; 
%   width = [[t_pre,0],[0,0]]; 
    end 
end 

end 

Erreur

Error using \ 
Requested 4800000x4800000 (171661.4GB) array exceeds 
maximum array size preference. Creation of arrays 
greater than this limit may take a long time and 
cause MATLAB to become unresponsive. See array size 
limit or preference panel for more information. 

Error in impulseresponse (line 13) 
    ffth = fftb/ffta; 
+6

Voulez-vous la division élément par élément ('. /')? (indice: oui, oui vous faites) –

+0

@AnderBiguri j'aime cet indice de la vôtre lol. le code est opérationnel. merci – iHateUni

Répondre

1

La barre oblique est un raccourci dans Matlab pour mrdivide(). Ceci est pour la résolution de systèmes d'équations matricielles linéaires. Ce que je pense que vous voulez est rdivide qui est désigné par ./.

  • c = a/b est seulement équivalent à la division standard si b est scalaire.

  • c = a./b est une division par élément, où chaque élément de a est divisé par l'élément correspondant de b.

    [1 2 3] ./ [2 4 9] 
    >> ans = [0.5, 0.5, 0.3333] 
    

Ainsi, la dernière ligne active de votre code "prévu de faire" devient

fft_h1 = fft_y1 ./ fft_x; 
+0

merci. le code fonctionne maintenant. mais est-ce mathématiquement correct? comme en division pour la transformée de Fourier. J'ai parcouru un site Web indiquant qu'il n'y a pas de division pour la matrice. cela fonctionne seulement en inversant la matrice comme A * A^-1. Ou est-ce que je me trompe? – iHateUni

+0

C'est une question mathématique très large, qui est l'une des premières choses à comprendre lorsqu'on apprend l'algèbre linéaire. S'il vous plaît poser des questions de maths sur math.stackoverflow.com ou poser une autre question d'algorithme spécifique ici, merci – Wolfie