Capturing in-car audio allows developers to interact with users by requesting raw audio data provided to them from the car's microphones. In order to gather the raw audio from the vehicle, you must leverage the PerformAudioPassThru
RPC.
SDL does not support automatic speech cancellation detection, so if this feature is desired, it is up to the developer to implement. The user may press an "OK" or "Cancel" button, the dialog may timeout, or you may close the dialog with EndAudioPassThru
.
SDL does not support an open microphone. However, SDL is working on wake-word support in the future. You may implement a voice command and start an audio pass thru session when that voice command occurs.
To initiate audio capture, first construct a PerformAudioPassThru
request. You must use a sampling rate, bit rate, and audio type supported by the head unit. To get the head unit's supported audio capture capabilities, check the sdlManager.getSystemCapabilityManager().getCapability(SystemCapabilityType.AUDIO_PASSTHROUGH)
after successfully connecting to the head unit.
Audio Pass Thru Capability | Parameter Name | Description |
---|---|---|
Sampling Rate | samplingRate | The sampling rate |
Bits Per Sample | bitsPerSample | The sample depth in bits |
Audio Type | audioType | The audio type |
PerformAudioPassThru performAPT = new PerformAudioPassThru(); performAPT.setAudioPassThruDisplayText1("Ask me \"What's the weather?\""); performAPT.setAudioPassThruDisplayText2("or \"What's 1 + 2?\""); performAPT.setInitialPrompt(TTSChunkFactory.createSimpleTTSChunks("Ask me What's the weather? or What's 1 plus 2?")); performAPT.setSamplingRate(SamplingRate._22KHZ); performAPT.setMaxDuration(7000); performAPT.setBitsPerSample(BitsPerSample._16_BIT); performAPT.setAudioType(AudioType.PCM); performAPT.setMuteAudio(false); sdlManager.sendRPC(performAPT);
SDL provides audio data as fast as it can gather it, and sends it to the developer in chunks. In order to retrieve this audio data, the developer must observe the OnAudioPassThru
notification.
This audio data is only the current chunk of audio data, so the developer must be in charge of managing previously retrieved audio data.
sdlManager.addOnRPCNotificationListener(FunctionID.ON_AUDIO_PASS_THRU, new OnRPCNotificationListener() { @Override public void onNotified(RPCNotification notification) { OnAudioPassThru onAudioPassThru = (OnAudioPassThru) notification; byte[] dataRcvd = onAudioPassThru.getAPTData(); processAPTData(dataRcvd); // Do something with audio data } });
The format of audio data is described as follows:
- It does not include a header (such as a RIFF header) at the beginning.
- The audio sample is in linear PCM format.
- The audio data includes only one channel (i.e. monaural).
- For bit rates of 8 bits, the audio samples are unsigned. For bit rates of 16 bits, the audio samples are signed and are in little endian.
PerformAudioPassThru
is a request that works in a different way than other RPCs. For most RPCs, a request is followed by an immediate response, with whether that RPC was successful or not. This RPC, however, will only send out the response when the audio pass thru has ended.
Audio capture can be ended in 4 ways:
Audio pass thru has timed out.
resultCode
of SUCCESS
. You should handle the audio pass thru though it was successful.Audio pass thru was closed due to user pressing "Cancel".
resultCode
of ABORTED
. You should ignore the audio pass thru.Audio pass thru was closed due to user pressing "Done".
resultCode
of SUCCESS
. You should handle the audio pass thru as though it was successful.Audio pass thru was ended due to the developer ending the request.
EndAudioPassThru
RPC. You will receive a resultCode
of SUCCESS
, and should handle the audio pass thru as though it was successful.EndAudioPassThru endAPT = new EndAudioPassThru(); sdlManager.sendRPC(endAPT);
To process the response received from an ended audio capture, monitor the PerformAudioPassThruResponse
by adding a listener to the PerformAudioPassThru
RPC before sending it. If the response has a successful result, all of the audio data for the passthrough has been received and is ready for processing.
performAPT.setOnRPCResponseListener(new OnRPCResponseListener() { @Override public void onResponse(int correlationId, RPCResponse response) { Result result = response.getResultCode(); if(result.equals(Result.SUCCESS)){ // We can use the data }else{ // Cancel any usage of the data Log.e("SdlService", "Audio pass thru attempt failed."); } } @Override public void onError(int correlationId, Result resultCode, String info){ Log.e(TAG, "onError: "+ resultCode+ " | Info: "+ info ); } });