Turning binary data into speaker output.

Hi I'm trying to come up with a code that turns binary data into an audio loudness signal for a presentation on air gapping.
I'm not entirely sure how but I would like to do it simply using Matlab to send a distinct loudness change output over time to the computer's speaker. Basically like morse code.
Any white noise audio file can be used as a base. I will be using a recording of a computer fan.
I am aiming for the following translation with 1 second between each:
1 - 80 dB (at your discretion)
0 - 50 dB (at your discretion)
00000 would be 5 seconds of the file at 50 dB
11111 would be 5 seconds of the file at 80 dB
Example:
Text: I love MATLAB :)
Binary: 01001001 00100000 01101100 01101111 01110110 01100101 00100000 01001101 01000001 01010100 01001100 01000001 01000010 00100000 00111010 00101001

 Accepted Answer

MATLAB cannot control the loudness of a sound. It can control the relative loudness, but not the absolute loudness. With Windows, you can make ActiveX calls to control the volume settings of your output device... but that cannot control the absolute loudness, just the electrical signal level being fed into your amplifier.
80 dB compared to 50 dB is 1000 times louder. The audio systems typically are 16 bit, so for the 50 dB sound you would have to restrict your samples to the +/- 0.001 range while your 80 dB would be the whole +/- 1.0 range.
[whitenoise, Fs] = audioread('WhiteNoiseSource.mp4');
noise5 = ifft( fft(whitenoise), Fs*5 );
n5L = length(noise5);
Text = 'I love MATLAB :)';
Binary = logical(reshape(dec2bin(Text, 8).', 1, []) - '0');
RelVol = 0.001 * ones(size(Binary));
RelVol(Binary) = 1;
BL = length(RelVol);
shaped_noise = repelem(RelVol, n5L) .* repelem(noise5, BL);
sound(shaped_noise, Fs)

6 Comments

Thanks, however, Matlab gave an error with repelem. Not sure if I need to download anything to use in this way.
Error using repelem
With two inputs, the first argument must be a vector. Use three-input syntax for matrices.
Error in carip (line 9)
shaped_noise = repelem(RelVol, n5L) .* repelem(noise5, BL);
Would it be possible to then just save this shaped noise as a file?
Ah, your noise file is not mono.
noisefile = '/WashingMachine-16-44p1-stereo-10secs.wav';
[whitenoise, Fs] = audioread(noisefile);
nchan = size(whitenoise, 2);
noise5 = abs(ifft( fft(whitenoise, [], 1), Fs*5 ));
n5L = size(noise5, 1);
Text = 'I love MATLAB :)';
Binary = logical(reshape(dec2bin(Text, 8).', [], 1) - '0');
RelVol = 0.001 * ones(size(Binary));
RelVol(Binary) = 1;
RelVol = repmat(RelVol, 1, nchan);
RL = size(RelVol,1);
shaped_noise = repelem(RelVol, n5L, 1) .* repmat(noise5, RL, 1);
audiowrite('shaped_noise.wav', shaped_noise, Fs);
On my system, using my built-in speakers, the 50dB version is not audible, and just sounds like silence for that period.
The noise5 computation I do in the code has the effect of resampling the frequency. A more refined code would do something like repeating the noise, or chopping off the appropriate amount of noise. Such as
if size(whitenoise, 1) > Fs*5
noise5 = whitenoise(1:Fs*5, :);
else
noise5 = abs(ifft( fft(whitenoise, [], 1), Fs*5 ));
end
Thanks again. Is this code creating the binary over 1 second? Seems like its taking a lot of time to switch maybe changing it to 0.5s intervals? I'm using a 5 minute audio file but it turns it into a 10:40 file. I would expect that the message would take 64s and then repeat over the file length. Not so sure where in the code I could fix this, I did change the dB to be audible.
00000 would be 5 seconds of the file at 50 dB
11111 would be 5 seconds of the file at 80 dB
Was your intention to group every 5 bits and use that as a fraction to interpolate between 50 and 80 dB? Because I just read it as indicating that every bit should result in 5 seconds of output. Perhaps every bit should result in 1 second of output?
My interpretation was that each bit should result in the sound (re-) playing for 5 seconds. Did you intend that instead the sound play through as many times as needed with the current bit indicating the loudness for 1 second, a loudness modulation rather than a repetition?
Yea so a bit was going for 1 second, but I found where to change it. So 5 bits would be 5 seconds not 25 seconds.
Do you happen to know if MATLAB could take audio input and graph it based on the loudness? Trying to use this example from splMeter. But I'm not sure how to use timescope, splMeter, etc data.
source = dsp.AudioFileReader('shaped_noise.wav');
fs = source.SampleRate;
player = audioDeviceWriter('SampleRate',fs);
scope = dsp.TimeScope('SampleRate',fs, ...
'TimeSpanOverrunAction','Scroll', ...
'TimeSpan',3,'ShowGrid',true, ...
'YLimits',[20 110],'AxesScaling','Auto', ...
'ShowLegend',true,'BufferLength',4*3*fs, ...
'ChannelNames', ...
{'Lt_AF','Leq_A','Lpeak_A','Lmax_AF'}, ...
'Name','Sound Pressure Level Meter');
SPL = splMeter('TimeWeighting','Fast', ...
'FrequencyWeighting','A-weighting', ...
'SampleRate',fs, ...
'TimeInterval',2);

Sign in to comment.

More Answers (0)

Categories

Find more on Audio Processing Algorithm Design in Help Center and File Exchange

Products

Release

R2020a

Community Treasure Hunt

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

Start Hunting!