use of android.media.AudioFormat in project platform_frameworks_base by android.
the class AudioPolicy method createAudioRecordSink.
/**
* Create an {@link AudioRecord} instance that is associated with the given {@link AudioMix}.
* Audio buffers recorded through the created instance will contain the mix of the audio
* streams that fed the given mixer.
* @param mix a non-null {@link AudioMix} instance whose routing flags was defined with
* {@link AudioMix#ROUTE_FLAG_LOOP_BACK}, previously added to this policy.
* @return a new {@link AudioRecord} instance whose data format is the one defined in the
* {@link AudioMix}, or null if this policy was not successfully registered
* with {@link AudioManager#registerAudioPolicy(AudioPolicy)}.
* @throws IllegalArgumentException
*/
@SystemApi
public AudioRecord createAudioRecordSink(AudioMix mix) throws IllegalArgumentException {
if (!policyReadyToUse()) {
Log.e(TAG, "Cannot create AudioRecord sink for AudioMix");
return null;
}
checkMixReadyToUse(mix, false);
// create an AudioFormat from the mix format compatible with recording, as the mix
// was defined for playback
AudioFormat mixFormat = new AudioFormat.Builder(mix.getFormat()).setChannelMask(AudioFormat.inChannelMaskFromOutChannelMask(mix.getFormat().getChannelMask())).build();
// create the AudioRecord, configured for loop back, using the same format as the mix
AudioRecord ar = new AudioRecord(new AudioAttributes.Builder().setInternalCapturePreset(MediaRecorder.AudioSource.REMOTE_SUBMIX).addTag(addressForTag(mix)).build(), mixFormat, AudioRecord.getMinBufferSize(mix.getFormat().getSampleRate(), // using stereo for buffer size to avoid the current poor support for masks
AudioFormat.CHANNEL_IN_STEREO, mix.getFormat().getEncoding()), AudioManager.AUDIO_SESSION_ID_GENERATE);
return ar;
}
use of android.media.AudioFormat in project platform_frameworks_base by android.
the class RecordingActivityMonitor method updateSnapshot.
/**
* Update the internal "view" of the active recording sessions
* @param event
* @param session
* @param source
* @param recordingFormat see
* {@link AudioSystem.AudioRecordingCallback#onRecordingConfigurationChanged(int, int, int, int[])}
* for the definition of the contents of the array
* @return null if the list of active recording sessions has not been modified, a list
* with the current active configurations otherwise.
*/
private List<AudioRecordingConfiguration> updateSnapshot(int event, int session, int source, int[] recordingInfo) {
final boolean configChanged;
final ArrayList<AudioRecordingConfiguration> configs;
synchronized (mRecordConfigs) {
switch(event) {
case AudioManager.RECORD_CONFIG_EVENT_STOP:
// return failure if an unknown recording session stopped
configChanged = (mRecordConfigs.remove(new Integer(session)) != null);
break;
case AudioManager.RECORD_CONFIG_EVENT_START:
final AudioFormat clientFormat = new AudioFormat.Builder().setEncoding(recordingInfo[0]).setChannelMask(recordingInfo[1]).setSampleRate(recordingInfo[2]).build();
final AudioFormat deviceFormat = new AudioFormat.Builder().setEncoding(recordingInfo[3]).setChannelMask(recordingInfo[4]).setSampleRate(recordingInfo[5]).build();
final int patchHandle = recordingInfo[6];
final Integer sessionKey = new Integer(session);
if (mRecordConfigs.containsKey(sessionKey)) {
final AudioRecordingConfiguration updatedConfig = new AudioRecordingConfiguration(session, source, clientFormat, deviceFormat, patchHandle);
if (updatedConfig.equals(mRecordConfigs.get(sessionKey))) {
configChanged = false;
} else {
// config exists but has been modified
mRecordConfigs.remove(sessionKey);
mRecordConfigs.put(sessionKey, updatedConfig);
configChanged = true;
}
} else {
mRecordConfigs.put(sessionKey, new AudioRecordingConfiguration(session, source, clientFormat, deviceFormat, patchHandle));
configChanged = true;
}
break;
default:
Log.e(TAG, String.format("Unknown event %d for session %d, source %d", event, session, source));
configChanged = false;
}
if (configChanged) {
configs = new ArrayList<AudioRecordingConfiguration>(mRecordConfigs.values());
} else {
configs = null;
}
}
return configs;
}
use of android.media.AudioFormat in project platform_frameworks_base by android.
the class SoundTriggerTestService method eventPayloadToString.
private String eventPayloadToString(SoundTriggerDetector.EventPayload event) {
String result = "EventPayload(";
AudioFormat format = event.getCaptureAudioFormat();
result = result + "AudioFormat: " + ((format == null) ? "null" : format.toString());
byte[] triggerAudio = event.getTriggerAudio();
result = result + "TriggerAudio: " + (triggerAudio == null ? "null" : triggerAudio.length);
result = result + "CaptureSession: " + event.getCaptureSession();
result += " )";
return result;
}
use of android.media.AudioFormat in project platform_frameworks_base by android.
the class BlockingAudioTrack method createStreamingAudioTrack.
private AudioTrack createStreamingAudioTrack() {
final int channelConfig = getChannelConfig(mChannelCount);
int minBufferSizeInBytes = AudioTrack.getMinBufferSize(mSampleRateInHz, channelConfig, mAudioFormat);
int bufferSizeInBytes = Math.max(MIN_AUDIO_BUFFER_SIZE, minBufferSizeInBytes);
AudioFormat audioFormat = (new AudioFormat.Builder()).setChannelMask(channelConfig).setEncoding(mAudioFormat).setSampleRate(mSampleRateInHz).build();
AudioTrack audioTrack = new AudioTrack(mAudioParams.mAudioAttributes, audioFormat, bufferSizeInBytes, AudioTrack.MODE_STREAM, mAudioParams.mSessionId);
if (audioTrack.getState() != AudioTrack.STATE_INITIALIZED) {
Log.w(TAG, "Unable to create audio track.");
audioTrack.release();
return null;
}
mAudioBufferSize = bufferSizeInBytes;
setupVolume(audioTrack, mAudioParams.mVolume, mAudioParams.mPan);
return audioTrack;
}
use of android.media.AudioFormat in project android_frameworks_base by AOSPA.
the class AudioPolicy method createAudioRecordSink.
/**
* Create an {@link AudioRecord} instance that is associated with the given {@link AudioMix}.
* Audio buffers recorded through the created instance will contain the mix of the audio
* streams that fed the given mixer.
* @param mix a non-null {@link AudioMix} instance whose routing flags was defined with
* {@link AudioMix#ROUTE_FLAG_LOOP_BACK}, previously added to this policy.
* @return a new {@link AudioRecord} instance whose data format is the one defined in the
* {@link AudioMix}, or null if this policy was not successfully registered
* with {@link AudioManager#registerAudioPolicy(AudioPolicy)}.
* @throws IllegalArgumentException
*/
@SystemApi
public AudioRecord createAudioRecordSink(AudioMix mix) throws IllegalArgumentException {
if (!policyReadyToUse()) {
Log.e(TAG, "Cannot create AudioRecord sink for AudioMix");
return null;
}
checkMixReadyToUse(mix, false);
// create an AudioFormat from the mix format compatible with recording, as the mix
// was defined for playback
AudioFormat mixFormat = new AudioFormat.Builder(mix.getFormat()).setChannelMask(AudioFormat.inChannelMaskFromOutChannelMask(mix.getFormat().getChannelMask())).build();
// create the AudioRecord, configured for loop back, using the same format as the mix
AudioRecord ar = new AudioRecord(new AudioAttributes.Builder().setInternalCapturePreset(MediaRecorder.AudioSource.REMOTE_SUBMIX).addTag(addressForTag(mix)).build(), mixFormat, AudioRecord.getMinBufferSize(mix.getFormat().getSampleRate(), // using stereo for buffer size to avoid the current poor support for masks
AudioFormat.CHANNEL_IN_STEREO, mix.getFormat().getEncoding()), AudioManager.AUDIO_SESSION_ID_GENERATE);
return ar;
}
Aggregations