Convert .txt/.mat to .wav format

I have a .txt and a .mat file, both containing the same data. I would like to convert either one(whichever is easier) to a .wav file so that I can play the sound and carry out audio processing. I understand 'wavwrite' is one way of doing this but so far I have been unsuccessful. I have tried:
>> load('data.mat')
>> hfile='data.wav';
>> wavwrite(y, Fs, hfile)
But when I run the code, it displays:
Undefined function or variable 'y'.
Does anyone know the solution to this problem or even an alternative method to convert a .txt/.mat file to .wav? Thanks

 Accepted Answer

load('data.mat')
will leave whatever the variable in the file name is as the variable in the workspace. Clearly it wasn't y.
Try
whos -file data.mat
and find out what that variable was that was written, then use it in the wavwrite call. Of course, you'll have to define Fs, too.
NB: documentation indicates
>> help wavwrite
wavwrite Write Microsoft WAVE (".wav") sound file.
wavwrite will be removed in a future release. Use AUDIOWRITE instead.
....
May want to take that into account.

15 Comments

I used 44100 as the sampling frequency, it displays data clipped on fifth line below, and the sound played was less that a second long. How do I know what to set the sampling frequency at?
>> load data.mat
>> sound_data = 'data.wav';
>> Fs = 44100;
>> audiowrite(sound_data,M,Fs);
Warning: Data clipped when writing file.
> In audiowrite>clipInputData (line 396)
In audiowrite (line 176)
>> clear M Fs
>> [M,Fs] = audioread(sound_data);
>> sound(M,Fs);
Clipping occurs if you pass floating point data and try to write to a file format that supports only integers.
The sample frequency would have been determined by the source of the data; there's no info available to us to know anything about from whence you got the data.
The time length will be 1/frequency*NumberSamples seconds in duration.
There's no information available in what you've posted to help with any of that; you'll have to find out all that from the data source (although you can look at the min|max() of the input to see about the scaling).
what is max(M(:)) and min(M(:)) and class(M) ?
I have attached the data file, if you could please help me. class(M) is double. max(M(:)) is 2.4500. min(M(:)) is 0.0800.
There's nothing to be learned from just the file, really. It looks kinda' like it might have come from a 0-255 uint8 as int8(M*100) would about span that range.
But, there's no information about sample rate altho one could use FFT to compute PSD and see what frequencies show up based on some assumptions of what are common data rates.
But, the question you've resolutely refused to answer remains--where did you get the .mat file from; that should tell you what it contains or whoever gave it to you should know.
You could wavewrite uint8(100*M)
dpb - sorry I didn't catch the question from your previous comment. The data is from an electronic stethoscope which forms the heart sounds. It has been sampled at 500Hz from an Arduino and the data was then captured to a text file using Cool-term. Attached is a plot of the data.
Walter - I tried audiowrite instead of wavewrite(it's been removed in my release), but it didn't work:
>> load('data.mat')
>> audiowrite uint8(100*M)
Error using audiowrite (line 100)
Not enough input arguments.
Well, that answers your earlier question of the sample frequency; it's 500 Hz. But, if your intent is to make a recording of it that will reproduce the audio it's too drastically undersampled to do that; the maximum frequency in the waveform is 250 Hz by the Nyquist theorem.
As far as the failure of audiowrite, read the doc files; it needs as a minimum three arguments--
audiowrite write audio files
audiowrite(FILENAME,Y,FS) writes data Y to an audio
file specified by the file name FILENAME, with a sample rate
of FS Hz.
....
audiowrite(hfile, uint8(M*100), 500)
I would like to make a recording to reproduce the audio. What sampling frequency would you recommend?
The below code does produce a .wav file however it doesn't replicate the sound of the original audio.
audiowrite(hfile, uint8(M*100), 500)
dpb
dpb on 26 Mar 2017
Edited: dpb on 27 Mar 2017
Well, you'll have to have an audio-capable recording device; CDs use the 44.1 kHz for a reason; that's what it takes to get audio quality sound.
What you'd have to have to cover the hearbeat depends on what the audible sound range covers which I don't really know...hmmm, gargle,gargle---well one medical instrumentation text shows
S1 30-45 hz
S2 50-70 hz
S3 <30 hz (weak)
S4 up to 600 hz (murmurs)
So, 250 hz Nyquist would seem to be marginal as to most of the above; what else? Well, there's not much resolution in the data, wonder if that is an issue?
Lesseee...
>> length(unique(int8(M*100)))/length(M)
ans =
0.0365
>>
Ewww!!! That is likely a serious problem; you've only got 3% of the observations being differently recorded levels; that's bound to be distorting the sounds even if the frequency is high enough. You need, I'd guess, at least another significant digit and two or more would help out of your instrument. That may or may not be sufficient in and of itself, but it's somewhere to start.
ADDENDUM
Note that if you "blow up" the x-axis of your sampled data to look closely at the first beat, it's clear the signal is grossly undersampled--the instrument may be providing a much finer sampling rate in real time, but what you're capturing is 3-4X too slow for an accurate rendition of the waveforms...here's just that first section:
All there is is a peak and minimum, nothing about the intermediary shape. Wonder if the device might not be doing some internal peak-holding and them updating those data rather than actual sampled data points given the regularity of the sampled data over the time period. Whatever it does/is doing isn't nearly enough to do such analyses on accurately, though.
I was mistaken in thinking that the sampling frequency was 500Hz. The data was sampled using an 'Arduino Due' and the sampling was done at the default rate(unknown at the moment) so my understanding is that the data has been over-sampled as opposed to under-sampled.
Is there any way to work out the sampling frequency from the data text file?
I understand that this is a Matlab forum but if you have some experience with Arduino's, do you know how to set the sampling frequency in the Arduino?
As said before, no, there's no way to tell what a sample rate was simply from the sampled data stream unless you know precisely what the input was and it was, say, a pure sine then you could potentially at least find a multiple that could be plausible, but you still couldn't say precisely what it was, specifically.
I've never seen an Arduino altho it looks like the Due has higher capabilities than early versions that definitely can be made to operate at higher speed. Just how fast it runs appears to be dependent upon how you did the data collection.
In a loop if there are print() statements outputting data, it's quite possible it's not fast at all; if it's using DMA and buffering the A/D, apparently it is possible to run up some very high sample rates. Need more info than have to have any clue what the actual data you have was sampled at, but certainly does NOT look to me to be oversampled; I'd surely expect to see some smooth waveforms in that case, not just jaggies.
How long did the subject data series take to acquire might have some indication but you need a lot more details and digging into the guts of the acquisition to know anything for certain; certainly just the data file as is isn't of any real help.
Thank you for your help dpb, much appreciated.
I will investigate the sampling rate issue and then after that look to try and convert it to a .wav file with the correct frequency.
I found a blog (somewhat dated, so may not be signficant, but then again...) that has some discussion of how the Due A/D is internally programmed. Depending upon how your device operates, it may be significant.
<DJErickson Arduino> The bottom-most section discusses what he learned about the A/D speed and how to set. There are some articles and code samples by a Stimmer that show how to write interrupt-driven DMA transfers for high-speed acquisition; perhaps that's what the instrument is doing? Or do you have to write code and what you have is just a sensor? Be interesting to see what it is you're actually using...but maybe some of this will help in your quest.
Post back what you find out...

Sign in to comment.

More Answers (0)

Asked:

on 25 Mar 2017

Commented:

dpb
on 28 Mar 2017

Community Treasure Hunt

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

Start Hunting!