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!