convert Wav file to binary, send it through simulink and convert it back to wav
46 次查看(过去 30 天)
显示 更早的评论
Hi,
i want to convert a .wav file (16Bit, 44100Hz, stereo) to a binary stream file, than send it through simulink via "Binary File Reader", read the Output from "Binary File Writer" back into Matlab and convert it back to .wav to hear the result of my Reverb i build with simulink.
my steps so far:
wavdata = audioread("Closed-Hi-Hat-1.wav");
wavbinary = dec2bin( typecast( single(wavdata(:)), 'uint8'), 8 ) - '0';
now i have a wavdata variable with value:3247x2 double
and a wavbinary with 25976x8 double
fid = fopen('wav.bin', 'w');
fwrite(fid, wavbinary);
fclose(fid);
I now have the "wav.bin" file i can add to my "Binary File Reader" in simulink, when i send it through my "Reverb" i get a new "wav_reverb.bin" file.
next steps back in matlab:
fid = fopen('wav_reverb.bin');
A = fread(fid);
sound(A);
when i now play (A) it sounds not like the actual "Closed-Hi-Hat-1.wav" i sent through my "Reverb". It sounds very bad and scratchy. I think its a problem with the data types. And i dont know how to convert the "wav_reverb.bin" back to a .wav (maybe it sounds better than).
PS: i tried the example from Walter
>> wavbinary = dec2bin( typecast( single(wavdata(:)), 'uint8'), 8 ) - '0';
>> orig_size = size(wavdata);
>> data_class_to_use = 'int32';
>> SampleRate = 22100;
>> wavdata = reshape( typecast( uint8(bin2dec( char(wavbinary + '0') )), data_class_to_use ), orig_size );
>> audiowrite('FileNameGoesHer33e.wav', wavdata, SampleRate)
but the new audiofile sounds also scratchy and bad.
I hope anyone can help me
thanks
LK
3 个评论
采纳的回答
Guillaume
2019-7-6
编辑:Guillaume
2019-7-8
I'm not entirely clear why you're jumping through so many hoops, but it looks like there's a misunderstanding. As far as I can tell (I don't have the required toolbox) a binary file reader is not intended to read streams of 0 and 1. It's intended to read streams of bytes as opposed to streams of characters. At least that's the common usage of binary file.
Sure, if you reconstruct the original data from your stream of 0 and 1 you should get back the same data but that's extremely wasteful. You start with double data = 8 bytes per samples, which you downcast to single by reducing the precision = 4 bytes per sample = 32 bits per sample. You then convert extract each bit and store each as double = 8 bytes per bit = 256 bytes per sample. So you've gone from having original data that takes 8 bytes per sample to slightly less precise data that takes 32 times more space.
You could just save the double wavdata into a file
fid = fopen('wav.bin', 'w');
fwrite(fid, wavdata, 'double');
fclose(fid);
and read that directly with the Binary File Reader.
3 个评论
Guillaume
2019-7-8
编辑:Guillaume
2019-7-8
I thought your signal had 3247 samples per channel, with 2 channels. So how did you get to 51952 samples (8 times as many).
Again, you should write your wav signals without any conversion with
fwrite(fid, wavdata, 'double');
(I initially forgot the 'double' in my answer).
And read it back with the binary file reader block, specifying type double for the storage data type, 2 for the numbers of channel, and probably 3247 for the samples per frame. I'm assuming the reader expect non-interleaved data, the documentation does not specify. If data is supposed to be interleaved you would have to transpose wavdata before writing it.
edit: Actually, it does say under Number of Channels that the data is interleaved (why don't they say that in the blurb at the top of the documentation? It's important!). So, to write your binary file you'd use:
wavdata = audioread("Closed-Hi-Hat-1.wav", 'double'); %Safer to force to double
%wavdata is a mxn array with m samples and n channels
fid = fopen('wav.bin', 'w');
fwrite(fid, wavdata', 'double'); %transpose the data so it is written interleaved
fclose(fid);
and you can read it in simulink with the options I've specified above.
更多回答(2 个)
Walter Roberson
2019-7-5
wavdata = audioread("Closed-Hi-Hat-1.wav", 'native');
wavbinary = uint8(reshape((dec2bin( wavdata(:), 8 ) - '0').', [], 1));
fid = fopen('wav.bin', 'w');
fwrite(fid, wavbinary, 'uint8');
fclose(fid);
fid = fopen('wav.bin', 'r');
A = fread(fid,'*uint8');
wavdata = uint16(reshape(bin2dec( char(reshape(A, 8, []).' + '0') ), [], 2));
SampleRate = 22100;
audiowrite('FileNameGoesHere.wav', wavdata, SampleRate)
Alaa Hesham
2019-12-16
If final_audio_output is output represented as vector of zeros and ones , the original audio file was matlab " handel.wav".
Final_audio_output is after I have done processing on it (modulation + adding noise , then demodulation)
scaled_audio=reshape(final_audio_output,[],8); % Orignal audio file was of size 292452*8 " handel.wav file"
t_scaled_audio= typecast( uint8(bin2dec(char(scaled_audio + '0 ') )), 'int32' ) % this is the format that should be entered
% to audiowrite
fs=8192
audiowrite('r_handel.wav',t_scaled_audio,fs)
0 个评论
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!