0

I am trying to assess how many audio drop outs are in a given sound file of an ecological soundscape.

Format: Wave
Samplingrate (Hertz):   192000
Channels (Mono/Stereo): Stereo
PCM (integer format):   TRUE
Bit (8/16/24/32/64):    16 

My project had a two element hydrophone. The elements were different brands/models, and we are trying to determine which element preformed better in our specific experiment. One analysis we would like to conduct is measuring how often each element had drop-outs, or loss of signal. These drop-outs are not signal amplitude related, in other words, the drop-outs are not caused by maxing out the amplitude. The element or the associated electronics just failed.

I've been trying to do this in R, as that is the program I am most familiar with. I have very limited experience with Matlab and regex, but am opening to trying those programs/languages. I'm a biologist, so please excuse any ignorance.

In R I've been playing around with the package 'seewave', and while I've been able to produce some very pretty spectrograms (which, to be fair, is the only context I've previously used that package). I attempted to use the envelope and automatic temporal measurements function within seewave (timer). I got some interesting, but opposite results.

    foo=readWave("Documents/DASBR/DASBR2_20131119$032011.wav", from=53, to=60, units="seconds")
    timer(foo, f=96000, threshold=6.5, msmooth=c(30,5), colval="blue")

I've altered the values of msmooth and threshold countless times, but that's just fine tinkering. What this function preforms is measuring the duration between amplitude peaks at the given threshold. What I need it to do either a) find samples in the signal without amplitude or b) measure the duration between areas without amplitude. I can work with either of those outputs. Basically I want to reverse the direction the threshold is measuring, does that make sense? So therefore any sample that is below a threshold will trigger a measurement, rather than any sample that is above the threshold.

I'm still playing with seewave to see how to produce the data I need, but I'm looking for a bit of guidance. Perhaps there is a function in seewave that will accomplish what I'm trying to do more efficiently. Or, if there is anyway to output the numerical data generated from timer, I could use the 'quantmod' package function 'findValleys' to get a list of all the data gaps.

So yeah, guidance is what I'm requesting, oh data crunching gods.

Cheers.

etgriffiths
  • 210
  • 2
  • 12
  • Welcome to StackOverflow. You risk your question being closed since it is so vague and broad. Can you try and make it more specific about a coding problem you have? – Andrie Jan 31 '14 at 18:30
  • I'm trying to use the R package seewave to find audio drop-outs in a sound stream. I've been trying the function timer (as seen above). timer can be used to find increases in amplitude, but not decreased. I'm interested in reversing that process. However, timer(foo, f=96000, threshold=rev(10) ... doesn't work. Or other attempts like that. If there is another function within the package seewave that I should be using, then I would appreciate the guidance. Is this still too broad? – etgriffiths Jan 31 '14 at 22:00

2 Answers2

0

This problem sounds reminiscent of power transfer problems often seen in electrical engineering. One way to solve the problem is to take the RMS (the root of the mean of the square) of the samples in the signal over time, averaged over short durations (perhaps a few seconds or even shorter). The durations where you see low RMS are where the dropouts are. It's analogous to the VU meters that you sometimes see on audio amplifiers - which indicate the power being transferred to the speakers from the amplifier.

mti2935
  • 11,465
  • 3
  • 29
  • 33
  • Hey! So, if I split foo (which is 7 seconds long) into 7 equal size chunks first and then run rms on them, is that how you would approach this? So like: foo1=readWave("Documents/DASBR/DASBR2_20131119$032011.wav", from=53, to=54, units="seconds") foo2=readWave("Documents/DASBR/DASBR2_20131119$032011.wav", from=54, to=55, units="seconds") foo3=readWave("Documents/DASBR/DASBR2_20131119$032011.wav", from=55, to=56, units="seconds") etc... rms(foo1,foo2,foo3,etc...) I'm sure there's a loop that would make this easier, too. But is that what you were suggesting?? Thank you! – etgriffiths Jan 31 '14 at 22:10
  • That's the jist of it. Then, for each 1-second segment, take each sample, square it, then take the mean of all of the squared samples, then take the square root of that. That will give you the RMS for that segment. The segments that have lower RMS's are your where your dropouts are. The RMS is the average power of the signal. See http://en.wikipedia.org/wiki/Root_mean_square for more info. – mti2935 Jan 31 '14 at 22:49
  • Thank you! This solved one issue I was having, and opened up more! So it goes with coding. :p – etgriffiths Feb 04 '14 at 17:47
0

I just wanted to summarize what I ended up doing so other people will be aware. Unfortunately, the RMS measurement is not what I was looking for. Though rms could technically give me a basic idea of drop-outs could occur, because I'm working with ecological recordings there are too many other factors at play.

Background: The sound streams I am working with are from a two element hydrophone, separated vertically by 2 meters and recording at 100 m below sea level. We are finding that the element sitting at ~100 meters is experiencing heavy drop outs, while the element at ~102 meters is mostly fine. We are currently attributing this to a to-be-identified electrical issue. If both elements were poised to receive auto exactly the same way, rms would work when detecting drop-outs, but because sound is received independently the rms calculation is too heavily impacted by other factors. Two meters can make a larger difference than you'd think when it comes to source levels and signal reception, it's enough for us to localize vocalizing animals (with left/right ambiguity) based on the delay between signal arrivals.

All the same, here's what I did:

library(seewave)
library(tuneR)
foo=readWave("Sound_file_Path")
L=foo@left
R=foo@right
rms(L)
rms(R)

I then looped this process through a directory, which I detail here: for.loop with WAV files

So far, this issue is still unresolved, but thank you for the discussion!

~etg

Community
  • 1
  • 1
etgriffiths
  • 210
  • 2
  • 12