2

I am trying to do some audio processing on Android in real time.

What I got so far, is an app that records a sound during a predefined amount on time and save it on a WAV file which is then processed.

This works pretty good but, since I am just interested on recording impulse responses, I have thought that it might be pretty cool to make my app automatically detect when has an impulse occured and just retain the samples from 0,5 seg before of the impulse and until 1,5 sec after (2 sec in total).

This is how I am dealing with the byte array of the wav file so far:

double audioSample = (double) (array[i+1] << 8 | array[i] & 0xff)/ 32767.0;

This gives me values between [-1,1], so lets say that my idea would be about considering an impulse any sound above 0,3 more or less. I think that the solution would be about storing the samples in a buffer and checking its values in real time but I am not quite sure about how to implement it.

Do you guys know any sample code or something I can take a look at?

paviflo
  • 105
  • 2
  • 13

1 Answers1

2

You're on the right track. You'll want to store your samples in a circular buffer that is exactly big enough to handle the number of pre trigger samples you want. You can find circular buffer code easily on the web or SO. Once your trigger condition is met, dump the contents of the circular buffer onto disk, set a condition and from there on record to disk. Here's some pseudo code to get you started.

void ProcessSamples(double[] samples)
{
    if (!triggered)
    {
        // write your level test here. Return -1 if you don't find anything
        // otherwise return the index of the sample.
        int triggerPos = SearchForTrigger(samples);
        if (triggerPos >= 0)
        {
            circularBuffer.Add(samples, triggerPos); // add up to the trigger pos
            WriteSamplesToFile(circularBuffer.GetSamples());
            triggered = true;
        }
        else
        {
            circularBuffer.Add(samples, samples.Length); // add all of the samples.
        }
    }
    else
    {
        WriteSamplesToFile(samples);
    }
}
jaket
  • 9,140
  • 2
  • 25
  • 44
  • I´ve been trying to work on this, but I am a little stucked with the sizes of the buffer arrays. If I want the circular buffer to give me 0,5 sec of samples, what size should it be? I know about AudioRecord.getMinBufferSize(RECORDER_SAMPLERATE, RECORDER_CHANNELS,RECORDER_AUDIO_ENCODING); but I don´t really know to what amount of time does that bufferSize corresponds – paviflo Jun 22 '14 at 10:53
  • It depends on the sampling rate. At 48kHz sampling rate there are 48000 samples/sec so a 0.5 second buffer would need to hold 24000 samples. Double that if you have two channels. My example was already compensating for the sample size by assuming the samples have been converted to doubles prior to buffering. – jaket Jun 23 '14 at 06:51
  • Can you help me with https://stackoverflow.com/questions/61184352/android-accessibility-service-real-time-audio-processing question – Feroz Siddiqui Apr 13 '20 at 08:53