Хорошо ... Я здесь опоздал на 5 лет ... но я сделал это для себя и хотел предложить решение!
У меня была такая же проблема с нехваткой памяти при записи больших файлов wav в Matlab. Я обошел это, отредактировав функцию wavwrite в matlab, чтобы она извлекала данные с вашего жесткого диска, используя memmap
вместо переменных, хранящихся в ОЗУ, а затем сохраняла их как новую функцию. Это избавит вас от многих проблем, так как вам не нужно беспокоиться о работе с заголовками при написании файла wav с нуля, и вам не понадобятся никакие внешние приложения.
1) введите edit wavwrite
, чтобы увидеть код функции, затем сохраните его копию как новую функцию.
2) Я изменил переменную y
в функции wavwrite
из массива, содержащего данные wav, в массив ячеек со строками, указывающими на расположение данных каждого канала, сохраненного на моем жестком диске. Разумеется, сначала используйте fwrite
для сохранения ваших wav-данных на жестком диске. В начале функции я преобразовал расположение файлов, хранящихся в y
, в переменные memmap и определил количество каналов и выборок следующим образом:
замените эти строки:
% If input is a vector, force it to be a column:
if ndims(y) > 2,
error(message('MATLAB:audiovideo:wavwrite:invalidInputFormat'));
end
if size(y,1)==1,
y = y(:);
end
[samples, channels] = size(y);
с этим:
% get num of channels
channels = length(y);
%Convert y from strings pointing to wav data to mammap variables allowing access to the data
for i = 1:length(y)
y{i} = memmapfile(y{i},'Writable',false,'Format','int16');
end
samples = length(y{1}.Data);
3) Теперь вы можете редактировать приватную функцию write_wavedat(fid,fmt)
. Это функция, которая записывает данные WAV. Превратите его во вложенную функцию, чтобы она могла читать вашу переменную y
memmap как глобальную переменную, вместо того, чтобы передавать значение функции и занимать вашу оперативную память, тогда вы можете внести некоторые изменения, например:
замените строки, которые записывают данные wav:
if (fwrite(fid, reshape(data',total_samples,1), dtype) ~= total_samples),
error(message('MATLAB:audiovideo:wavewrite:failedToWriteSamples'));
end
с этим:
%Divide data into smaller packets for writing
packetSize = 30*(5e5); %n*5e5 = n Mb of space required
packets = ceil(samples/packetSize);
% Write data to file!
for i=1:length(y)
for j=1:packets
if j == packets
fwrite(fid, y{i}.Data(((j-1)*packetSize)+1:end), dtype);
else
fwrite(fid, y{i}.Data(((j-1)*packetSize)+1:j*packetSize), dtype);
end
disp(['...' num2str(floor(100*((i-1)*packets + j)/(packets*channels))) '% done writing file...']);
end
end
Это будет постепенно копировать данные из каждой переменной memmap в wav-файл.
4) Так и должно быть! Вы можете оставить остальной код как есть, так как он напишет заголовки за вас. Вот пример того, как вы могли бы написать большой двухканальный wav-файл с помощью этой функции:
wavwriteModified({'c:\wavFileinputCh1' 'c:\wavFileinputCh2'},44100,16,'c:\output2ChanWavFile');
Я могу убедиться, что этот подход работает, так как я только что написал 4-канальный wav-файл 800 МБ с моей отредактированной функцией wavwrite, когда Matlab обычно выдает ошибку out of memmory
для записи файлов wav размером более 200 МБ для меня.
person
RTbecard
schedule
05.07.2015