35

I'm attempting to use AudioRecord with AudioSource.VOICE_DOWNLINK on Nexus 5X, Android 7.1 (my own build from AOSP).

I'm already past the permissions stage - moved my APK to privileged apps, made an adjustment to AudioRecord in Android source to stop throwing an exception about this source.

Now I'm getting empty recording buffers during a phone call.

I know that there are a lot of call recording apps, and they work on other devices. I've also seen certain apps that can perform some hack on a rooted N5 and make it work.

I wish to achieve the same on Nexus 5X - ANY adjustment is OK for me, including changing Android version, modifying Qualcomm drivers, device configuration files, etc. - basically anything that can be achieved in a custom ROM.

I've tried messing around with platform code - hardware/qcom/audio/hal/voice.c, especially the function voice_check_and_set_incall_rec_usecase, but could not make sense out of it so far.

Also checked device/lge/bullhead/mixer_paths.xml, found there's a section related to call recording:

<!-- Incall Recording -->
<ctl name="MultiMedia1 Mixer VOC_REC_UL" value="0" />
<ctl name="MultiMedia1 Mixer VOC_REC_DL" value="0" />
<ctl name="MultiMedia8 Mixer VOC_REC_UL" value="0" />
<ctl name="MultiMedia8 Mixer VOC_REC_DL" value="0" />
<!-- Incall Recording End -->

But I also couldn't make sense out of it or how it can be helped.

SirKnigget
  • 3,614
  • 2
  • 28
  • 61
  • Are you getting any expection? – Nouman Ghaffar May 25 '17 at 04:44
  • try putting audioRecoder.record() in a try catch and check . Also post your recording code a bit. – Nouman Ghaffar May 25 '17 at 04:46
  • There is no crash, so there is no point in try-catch. – SirKnigget May 25 '17 at 11:36
  • the SLIMbus℠ "Serial Low-Power Inter-Chip Media Bus" is being used. the only way to get access to that audio stream is to change the way the ALSA mixer assigns the audio paths. newer versions of Android now have `Incoming Call Options` > `Record call (4)` (press and hold key `4`?); however the SDK does not provide access to any of that. https://developer.android.com/guide/topics/media/mediaplayer.html ...explains it (per default, one can only playback trough the default audio device). – Martin Zeitler Jul 28 '17 at 05:10
  • Hi Martin, I don't need the SDK - modifying AOSP is OK for me. Do you have any idea how to do what you said for Nexus 5X? – SirKnigget Jul 28 '17 at 11:43

1 Answers1

1

Not sure if it is a Nexus 5 specific issue but usually the class used to record calls is MediaRecorder. Have you tried to replace AudioRecorder by a MediaRecorder?

Based on this stack-overflow question, I think you could try the following code based on Ben blog post:

import android.media.MediaRecorder;
import android.os.Environment;

import java.io.File;

import java.io.IOException;


public class CallRecorder {

    final MediaRecorder recorder = new MediaRecorder();
    final String path;

    /**
     * Creates a new audio recording at the given path (relative to root of SD card).
     */
    public CallRecorder(String path) {
        this.path = sanitizePath(path);
    }

    private String sanitizePath(String path) {
        if (!path.startsWith("/")) {
            path = "/" + path;
        }
        if (!path.contains(".")) {
            path += ".3gp";
        }
        return Environment.getExternalStorageDirectory().getAbsolutePath() + path;
    }

    /**
     * Starts a new recording.
     */
    public void start() throws IOException {
        String state = android.os.Environment.getExternalStorageState();
        if(!state.equals(android.os.Environment.MEDIA_MOUNTED))  {
            throw new IOException("SD Card is not mounted.  It is " + state + ".");
        }

        // make sure the directory we plan to store the recording in exists
        File directory = new File(path).getParentFile();
        if (!directory.exists() && !directory.mkdirs()) {
            throw new IOException("Path to file could not be created.");
        }

        recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_CALL);
        recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        recorder.setOutputFile(path);
        recorder.prepare();
        recorder.start();
    }

    /**
     * Stops a recording that has been previously started.
     */
    public void stop() throws IOException {
        recorder.stop();
        recorder.release();
    }

}

In this sample, I've used MediaRecorder.AudioSource.VOICE_CALL but you can test other options like MediaRecorder.AudioSource.VOICE_COMMUNICATION and also the microphone just to see if there are any hardware issues on your phone.

Faysal Ahmed
  • 7,501
  • 5
  • 28
  • 50
Marcio Jasinski
  • 1,439
  • 16
  • 22
  • I need to use AudioRecord to record in real time. – SirKnigget May 24 '17 at 20:34
  • **Now I'm getting empty recording buffers during a phone call** - is it because both AudioRecorder and call using the same channel???? have u tried listening to some different sources, like putting the call on speaker and then try – Debu May 25 '17 at 07:32
  • I am not interested in putting the call on speaker, I need to record the call properly from AudioSource.VOICE_CALL. – SirKnigget May 25 '17 at 11:35
  • I see. So maybe you could share you code and it would be easier to see whats going on. AudioRecorder is not so common as MediaRecorder but there is a nice sample here - note that you need to run it in a separated thread: https://www.newventuresoftware.com/blog/record-play-and-visualize-raw-audio-data-in-android – Marcio Jasinski May 26 '17 at 01:18