好的......我在这里迟到了 5 年......但我只是为自己做了这个,并想把解决方案放在那里!
在 matlab 中编写大型 wav 文件时,我遇到了内存不足的问题。我通过编辑 matlab wavwrite 函数解决了这个问题,因此它使用memmap
而不是存储在 RAM 上的变量从硬盘驱动器中提取数据,然后将其保存为新函数。这将为您省去很多麻烦,因为您在从头开始编写 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 变量作为全局变量读取,而不是将值传递给函数并吃掉你的 RAM,然后你可以做一些这样的改变:
替换写入 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 变量增量复制到 wavfile
4)应该是这样!您可以保留其余代码,因为它会为您编写标题。下面是如何使用此函数编写大型 2 通道 wav 文件的示例:
wavwriteModified({'c:\wavFileinputCh1' 'c:\wavFileinputCh2'},44100,16,'c:\output2ChanWavFile');
我可以验证这种方法是否有效,因为我刚刚使用我编辑的 wavwrite 函数编写了一个 800mB 4 通道 wav 文件,而当 matlab 为我编写大于 200mb 的 wav 文件时通常会抛出out of memmory
错误。