Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Superpowered SDK Record and Playback simultaneously

My goal is to play local file while recording device's microphone input with low-latency. I've come to Superpowered library, because from the documentation it provides low-latency feature. I've created the player using SuperpoweredAdvancedAudioPlayer and SuperpoweredAndroidAudioIO and it plays fine.

SuperpoweredAndroidAudioIO has the construcor with parameters boolean enableInput, boolean enableOutput. Currently I'm using enableInput == false and enableOutput == true. When I put these parameters to true - no effect.

I wonder if it is possible to record file and play other file simultaneously?

Also there is SuperpoweredRecorder class in library but it says not for direct writing to disk. And need to use createWAV, fwrite, closeWAV methods. I've tried implement Recorder separately but the quality is not good (it is two-three times faster than real recording + sound is distored). Here is the simplest piece of code for recording I used:

void SuperpoweredFileRecorder::start(const char *destinationPath) {
    file = createWAV(destinationPath, sampleRate, 2);
    audioIO = new SuperpoweredAndroidAudioIO(sampleRate, bufferSize, true, false, audioProcessing, NULL, bufferSize); // Start audio input/output.
}

void SuperpoweredFileRecorder::stop() {
    closeWAV(file);
    audioIO->stop();
}

static bool audioProcessing(void *clientdata, short int *audioInputOutput, int numberOfSamples, int samplerate) {
    fwrite(audioInputOutput, sizeof(short int), numberOfSamples, file);
    return false;
}

Probably I cannot use Superpowered for that purpose and need to just make recording with OpenSL ES directly.

Thanks in advance!

like image 895
kasurd Avatar asked Nov 20 '15 13:11

kasurd


2 Answers

After experiments I found the solution.

  1. SuperpoweredRecorder works fine for recording tracks;
  2. I've created to separate SuperpoweredAndroidAudioIO sources - one for playback and another for recorder. After some synchronization manipulation it works well (I minimized latency to very low level, so it suits my needs).

I post some code snippet with the idea I implemented:

https://bitbucket.org/snippets/kasurd/Mynnp/nativesuperpoweredrecorder-with

Hope it helps somebody!

like image 69
kasurd Avatar answered Oct 16 '22 21:10

kasurd


You can do this with one instance of the SuperpoweredAndroidAudioIO with enableInput and enableOutput set to true.

The audio processing callback (audioProcessing() in your case) receives audio (microphone) in the audioInputOutput parameter. Just pass that to your SuperpoweredRecorder, and it will write it onto disk.

After that, do your SuperpoweredAdvancedAudioPlayer processing, and convert the result into audioInputOutput. That will go to the audio output.

So it's like, in pseudo-code:

audioProcessing(audioInputOutput) {
   recorder->process(audioInputOutput)
   player->process(some_buffer)
   float_to_short_int(some_buffer, audioInputOutput)
}

Never do any fwrite in the audio processing callback, as it must complete within a very short time, and disk operations may be too slow.

like image 22
Gabor Szanto Avatar answered Oct 16 '22 19:10

Gabor Szanto