The function SystemDialogInput["RecordSound"]
brings up an interface that lets you record a sound object. Let's say we first record a one second long snippet of background noise called background
. Afterwards we record two short snippets sn1
and sn2
one of which again contains only the background noise, while the second one contains the sound of our voice. Is there any function in Mathematica which could use background
as a gauge and tell us as computationally efficient as possible which of the two snippets contains the voice?
1 Answer
Here is my solution. After recording the snippets and background using SystemDialogInput["RecordSound"]
, send the sound objects through a BandpassFilter
to restrict to voice frequencies only:
background = BandpassFilter[background, {300, 3400}];
sn1 = BandpassFilter[sn1, {300, 3400}];
sn2 = BandpassFilter[sn2, {300, 3400}];
Then we can see if the maximum amplitude in either of the snippets is higher than the one in background
:
mback=Max[Abs[background /. Sound[{SampledSoundList[x_, y_]}]-> x]];
msn1=Max[Abs[sn1 /. Sound[{SampledSoundList[x_, y_]}]-> x]];
msn2=Max[Abs[sn2 /. Sound[{SampledSoundList[x_, y_]}]-> x]];
thresh=5;
If[msn1/mback>thresh,Print["sn1 is voice"],Print["sn1 no voice"]]
If[msn2/mback>thresh,Print["sn2 is voice"],Print["sn2 no voice"]]
Here the threshold was set to max amplitude of voice being at least 5
times bigger than background noise. I set it to this value, since on average my voice got a score of about 10
in this fraction.
-
1$\begingroup$ I'd compare the total power in band rather than just the max amplitude. (Total power =
Total[Abs[signal]^2])/Length@signal
It'll probably be a slightly better comparison, and you can express it in dB above background by taking10*Log[voicePower/backgroundPower]
. $\endgroup$ Aug 21, 2015 at 13:00 -
1