13

I currently need to capture the moment when an outgoing call begins ringing. According to Abeer Ahmad in "How to identify the ringing state of outgoing call in android", a solution would be to detect the frequency change of the emitted sound (from 0 to the value corresponding to the ring) using the Visualizer class. However, no frequency value other than 0 (silence) is detected while I make a call. This does not correspond to what happens when the mobile emits another sound, such as the reproduction of an audio track, where the frequency values are detected. Could someone help me, or give me an alternative solution?

Here is my code:

mVisualizer = new Visualizer(0);
mVisualizer.setCaptureSize(Visualizer.getCaptureSizeRange()[1]);
Visualizer.OnDataCaptureListener listener = new Visualizer.OnDataCaptureListener(){
                    @Override
                    public void onWaveFormDataCapture(Visualizer visualizer, byte[] bytes, int samplingRate) { }
                    @Override
                    public void onFftDataCapture(Visualizer visualizer, byte[] bytes, int samplingRate) {
                        for (int i=0;i<bytes.length;i++) {
                            if (bytes[i] != 0) {
                              Log.i("INFO","FREQUENCY:"+bytes[i]);
                                break;
                            }
                        }
                    }
                };
mVisualizer.setDataCaptureListener(listener, Visualizer.getMaxCaptureRate() / 2, true, true);

I'm using Android Jellybean (API 17).

Community
  • 1
  • 1

1 Answers1

0

Calling new Visualizer(0); listens to Stream 0, the mixed output.

The issue is call audio isn't always present in the mixed output as indicated on this Google Bug so you need to find the correct stream yourself. However, I haven't found a simple way to do this.

MediaPlayer used to have a non-public snoop method which could be utilized but it was removed from recent versions. A long shot you could try is creating an audio track on the same stream and listening to that session id:

AudioTrack track = new AudioTrack(AudioManager.STREAM_VOICE_CALL, aSampleRate, 
        AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, 
        aBuffersize, AudioTrack.MODE_STREAM);

You could also try calling audioManager.setStreamSolo(AudioManager.STREAM_VOICE_CALL, true); before starting your visualizer. In theory as STREAM_VOICE_CALL will become the only session allowed to produce audio, it should affect the results of the visualizer.

Note: If you look at generateAudioSessionId in AudioManager sources you'll see it uses the Native AudioSystem class. I would suggest it's possible to use the NDK to access this class and find current audio session id's

Nick Cardoso
  • 20,807
  • 14
  • 73
  • 124
  • Thanks for the help, but no one of your answers solve the problem. I tryed with both your recomendations and I still getting frequency = 0. This is very weird. I'm starting to think that there's not exists a solution for this problem. – Michel Escalante Álvarez Mar 13 '17 at 14:12
  • I did a search myself - there is no solution, that's why I was interested (there are 4 other unanswered questions like yours). It seems Google didn't provide a way to access all audio session id's for security purposes – Nick Cardoso Mar 13 '17 at 14:18
  • I also made a research about this topic and reached the same conclusion than you. I published this question hoping for someone could knows a "magical" or alternative solution for this issue. I really don't understand the "security problem" off allow this functionality in the Android API, 'cause this could be easily managed with the current permissions mechanism. It's a shame and I hope that soon appears a way to achieve this. Anyway, thanks again for your help. Regards. – Michel Escalante Álvarez Mar 13 '17 at 14:46
  • If you have the C++ skills you can look into the NDK (see my edit). I'm not familiar enough with it to give any direction though. – Nick Cardoso Mar 13 '17 at 14:48
  • this is not an answer to this question at all. I'm at a loss as to why this was posted as an answer. – yams Jun 17 '22 at 14:39