New to signal processing, but making good progress, I think.
I have a series of (many) impulses I generated, which will be used as impulse responses to model our church's acoustics, in this time of covid-19.
A couple of questions, before the details:
What is the best practice (and code solution) for detecting the onset of an impulse?
When considering the spectrogram for an impulse, is it unusual for the spectrogram's data to occur earlier than the waveform, and before the waveform(db)?
Details:
Slap-boards were used to generate the impulses, which were recorded as 2 channel WAV files at 96000, 16bits, using my zoom H1n Handy Recorder. The impulses occur at quite regular times in the data, although not precisely regular, as the board slaps were done by hand, at the beat of my internal drummer, so to speak.
I have successfully used scipy.io.wavfile to split the data into two channels, and then used scipy.signal.find_peaks to get (very close to) the onset of each of the pulses by finding the peak of each impulse. However, I can see that the actual onset of each impulse is missed by this approach, and I would like to capture these individual onsets better using python.
I've been reading up, and am sure this is a deep and broad topic. However, perhaps some kind soul can assist me with the specifics of how to find the precise times of these onsets? I imagine this is a fairly typical type of problem in signal processing, and I realize it's (quite) a bit of an education that I'm requesting.
I'm really hoping for a code solution suggestion to find the onset of these kind of impulse data.
To be clear,
a) The maximum peak for each pulse is not at the onset, obviously, nor is it necessarily the first noticeable peak for each impulse, as I review the entire datastream. (I think when this delayed peak occurs, a reflected signal has a higher peak than the direct response at the recording device. I'm not certain of this though . . .)
b) The waveforms for these pulses do not necessarily go to zero between impulses, in fact, they rarely do. The signal goes close to zero, but not precisely. (I expect this has something to do with ambient noise around the signal, but am not certain . . .)
c) The waveform could go negative first, or positive (as is the case with the (initial) data from this sample impulse).
In the attached image, the top five graphs show a group of impulses (3 out of several hundred), followed by increasing resolutions zooming into the onset of the first impulse in this group.
The bottom two images are the left channel of the first impulse, taken as screenshots from Audacity. They show the waveform, the waveform(db), and the spectrogram for the first impulse -- on the left, the entire impulse, on the right, the onset of the impulse. (I am puzzled why the spectrogram appears to precede the waveform and waveform(db) by a measurable number of samples.)
Although I plotted the spectrograms in Audacity, I am not sure how to access spectral data in a WAV file, nor how to use it for detecting the onset of an impulse.
I'll try to attach the data leading up to the first impulse, and a little ways into this impulse, but these are quite large files. I don't the rules for sending large datasets.
Thanks for your help, kind ones.
I am not sure of what is going on in a WAV file, but here are 250 samples taken from the left channel, that I believe start from before the onset of the first impulse, and end somewhat into the impulse itself:
wav_left_subset = array([
-23, -16, -20, -19, -18, -19, -15, -20,
-18, -21, -20, -22, -22, -18, -22, -17,
-22, -20, -17, -24, -14, -21, -16, -16,
-16, -13, -17, -11, -18, -14, -18, -14,
-16, -13, -12, -13, -9, -16, -11, -16,
-16, -13, -16, -14, -14, -15, -13, -13,
-11, -14, -9, -12, -12, -13, -15, -13,
-15, -15, -13, -16, -8, -14, -12, -12,
-13, -11, -11, -12, -10, -8, -8, -8,
-6, -9, -6, -7, -5, -6, -2, -3,
-2, -1, -4, -2, -4, -1, 0, -1,
2, 0, -1, 3, -3, 6, -2, 9,
4, 5, 7, 4, 7, 9, 1, 10,
6, 11, 13, 9, 13, 15, 12, 18,
15, 17, 20, 20, 22, 20, 21, 23,
20, 23, 25, 24, 32, 27, 33, 30,
32, 29, 33, 34, 36, 41, 39, 43,
42, 49, 47, 55, 51, 59, 60, 63,
67, 67, 72, 70, 78, 75, 83, 85,
88, 93, 96, 102, 106, 111, 115, 124,
127, 135, 143, 146, 161, 163, 181, 185,
197, 209, 222, 239, 249, 269, 281, 303,
322, 344, 369, 399, 431, 466, 501, 544,
588, 642, 701, 779, 858, 1003, 1152, 1466,
1706, 1921, 1352, -13, -4626, -11419, -14567, -17320,
-19721, -21829, -23673, -14863, -2840, 2088, 6363, 10091,
13343, 16173, 18656, 20820, 22727, 24392, 25864, 27162,
28305, 29329, 29056, 30424, 31358, 31919, 28408, 22294,
15638, 8584, 1428, -3153, -7130, -10605, -13629, -4656,
5684, 9787, 13358, 16474, 19186, 14213, 8269, 6929,
12547, 18601, 21081, 23248, 25145, 26811, 28274, 28920,
13555, 5571], dtype=int16)