convert Wav file to binary, send it through simulink and convert it back to wav

96 visualizzazioni (ultimi 30 giorni)
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 Commenti
Lukas Kuhl
Lukas Kuhl il 5 Lug 2019
Modificato: Lukas Kuhl il 5 Lug 2019
what do you mean with "uint8 that" ? you mean a typecast to 'uint8' and than typecast(A, 'single')?
so far i did:
A = uint8(A);
A = reshape(A, [ ], 8)
and i get a 1024x8 uint8 value...
when i A = typecast(A, 'single') i get
Error using typecast
The first input argument must be a vector.

Accedi per commentare.

Risposta accettata

Guillaume
Guillaume il 6 Lug 2019
Modificato: Guillaume il 8 Lug 2019
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 Commenti
Guillaume
Guillaume il 8 Lug 2019
Modificato: Guillaume il 8 Lug 2019
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.
edit again: But why don't you use the From multimedia file block to read your wav file directly?
Lukas Kuhl
Lukas Kuhl il 24 Lug 2019
thx for your answers and help. Since the project was stopped i dont need a solution right now. But anyway it's good to know for some future projects.
"edit again: But why don't you use the From multimedia file block to read your wav file directly?"
  • because my prof. wants me to compare the bitstream of two different programs, Matlab and Vivado.
anyway, it's not longer needed.
Thank you all, this thread can be closed!

Accedi per commentare.

Più risposte (2)

Walter Roberson
Walter Roberson il 5 Lug 2019
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)
  1 Commento
Lukas Kuhl
Lukas Kuhl il 6 Lug 2019
Hi Walter,
thanks for your help, i really appreciate it!
It seems like i get the right data types now. But neither my new wave sample comes close to the original reverbed soundfile nor to the uneffected soundfile.
I think i have a gross error of thinking in it, this couldnt be so hard, could it?
thank you anyway,
regards
Lukas

Accedi per commentare.


Alaa Hesham
Alaa Hesham il 16 Dic 2019
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)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by