💾 Archived View for heavysquare.com › noise › 1000-00-00-splitting-on-beeps.txt captured on 2023-04-19 at 23:10:50.
⬅️ Previous capture (2021-12-03)
-=-=-=-=-=-=-
The tools I used were: [sox](http://sox.sourceforge.net/) and [octave](https://www.gnu.org/software/octave/). The first step is to somehow create a textual data of your wave file with sox. Sox supports this by default, you could do something like this with the following command sox -S file.wav file.dat This can be huge, but managable nowadays (10-15 times the size of the wave file). As a next step you have to prepare this file to be parsable by octave. sed -i '1,2 d' file.dat LEN=`cat file.dat | wc -l` cat >matrix.txt <<EOF # Created by X # name: wave # rows: $LEN # columns: 3 EOF cat file.dat >> matrix.txt rm file.dat octave The columns for me was 3 as it was a stereo file (first column is time). The first two lines removed from file.dat are not data. After this you could go to octave and do a spectrogram. load -text "matrix.txt" n=128 window=hanning(n); Fs=44100 overlap = length(window)/2 win_size = length(window) step = win_size - overlap offset = [1:step:length(wave)-win_size]; S=zeros(n,length(offset)); for i=1:length(offset) S(1:win_size,i)=wave(offset(i):offset(i)+win_size-1,2) .* window; end S = fft(S); ret_n = n/2 S=S(1:ret_n,:); imagesc (20*log10(flipud(abs(S)))); ![spectro1](/im/spectro1.jpg "full") You will see a spectrogram like the one above. You could certainly spot the places where the beep sounds. Hover your mouse on one of the beeps, and read the column. In case it is too long, you could just plot one slice of your data as follows imagesc (20*log10(flipud(abs(S(:,2000:5000))))); ![spectro2](/im/spectro2.jpg "slice") You can see that the middle of my beep was at 1000 on the second plot, which makes column 3000 a good pattern for the beep frequency distribution. Now you can just subtract this from your data and sum up the frequency energies to get some plot of the beeps: beepcol=3000 Sabs=abs(S); beeper=repmat(Sabs(:,beepcol),1,length(Sabs)); Sbeep=abs(Sabs - beeper); energysum=sum(Sbeep); plot(energysum) ![energy](/im/energy.jpg "energy") From this third plot, the thing you have to read is a good threshold which separates data and beep. For me, 35 seems to be perfect. With this value you can construct the series of intervals that represent the data between the beeps. cutter=35 needed=(energysum > cutter); intervals=[] if needed(1)==1 intervals=[1,-1]; end for i=2:length(needed) if needed(i-1)==1 && needed(i)==0 intervals(1,2)=i; end if needed(i-1)==0 && needed(i)==1 intervals=[i,-1;intervals]; end end if intervals(1,2)==-1 intervals(1,2)=length(needed); end intervals=(intervals*overlap)/Fs; intervals=[intervals(:,1),intervals(:,2)-intervals(:,1)]; save -text "intervals.txt" intervals exit Now you have your list of intervals, you could use your shell and sox to automate the extraction of data, something like this: % tac intervals.txt| sed -n '/^ / p' | head -4 0.00145124716553288 4.003990929705216 5.259319727891157 2.461315192743764 8.974512471655329 1.497687074829932 11.72607709750567 2.182675736961452 % tac intervals.txt | sed -n '/^ / p' | \ head -1 | xargs sox file out1.wav trim That's it.