blob: bc94ea498006a12afeae7d30bf1204a3d7a5913a [file] [log] [blame]
/*
* Copyright 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.hyphonate.megaaudio.duplex;
import android.media.AudioDeviceInfo;
import android.util.Log;
import org.hyphonate.megaaudio.common.BuilderBase;
import org.hyphonate.megaaudio.common.StreamBase;
import org.hyphonate.megaaudio.player.AudioSource;
import org.hyphonate.megaaudio.player.AudioSourceProvider;
import org.hyphonate.megaaudio.player.Player;
import org.hyphonate.megaaudio.player.PlayerBuilder;
import org.hyphonate.megaaudio.recorder.AudioSink;
import org.hyphonate.megaaudio.recorder.AudioSinkProvider;
import org.hyphonate.megaaudio.recorder.Recorder;
import org.hyphonate.megaaudio.recorder.RecorderBuilder;
public class DuplexAudioManager {
private static final String TAG = DuplexAudioManager.class.getSimpleName();
// Player
//TODO - explain these constants
private int mNumPlayerChannels = 2;
private int mPlayerSampleRate = 48000;
private int mNumPlayerBufferFrames;
private Player mPlayer;
private AudioSourceProvider mSourceProvider;
private AudioDeviceInfo mPlayerSelectedDevice;
// Recorder
private int mNumRecorderChannels = 2;
private int mRecorderSampleRate = 48000;
private int mNumRecorderBufferFrames;
private Recorder mRecorder;
private AudioSinkProvider mSinkProvider;
private AudioDeviceInfo mRecorderSelectedDevice;
private int mInputPreset = Recorder.INPUT_PRESET_NONE;
public DuplexAudioManager(AudioSourceProvider sourceProvider, AudioSinkProvider sinkProvider) {
mSourceProvider = sourceProvider;
mSinkProvider = sinkProvider;
}
public void setInputPreset(int preset) { mInputPreset = preset; }
public int setupStreams(int playerType, int recorderType) {
// Recorder
if ((recorderType & BuilderBase.TYPE_MASK) != BuilderBase.TYPE_NONE) {
try {
mRecorder = new RecorderBuilder()
.setRecorderType(recorderType)
.setAudioSinkProvider(mSinkProvider)
.build();
if (mInputPreset != Recorder.INPUT_PRESET_NONE) {
mRecorder.setInputPreset(mInputPreset);
}
mRecorder.setRouteDevice(mRecorderSelectedDevice);
int errorCode = mRecorder.setupStream(
mNumRecorderChannels, mRecorderSampleRate, mNumRecorderBufferFrames);
if (errorCode != StreamBase.OK) {
Log.e(TAG, "Recorder setupStream() failed");
return errorCode;
}
mNumRecorderBufferFrames = mRecorder.getNumBufferFrames();
} catch (RecorderBuilder.BadStateException ex) {
Log.e(TAG, "Recorder - BadStateException" + ex);
return StreamBase.ERROR_UNSUPPORTED;
}
}
// Player
if ((playerType & BuilderBase.TYPE_MASK) != BuilderBase.TYPE_NONE) {
try {
mNumPlayerBufferFrames =
Player.calcMinBufferFrames(mNumPlayerChannels, mPlayerSampleRate);
mPlayer = new PlayerBuilder()
.setPlayerType(playerType)
.setSourceProvider(mSourceProvider)
.build();
mPlayer.setRouteDevice(mPlayerSelectedDevice);
int errorCode = mPlayer.setupStream(
mNumPlayerChannels, mPlayerSampleRate, mNumPlayerBufferFrames);
if (errorCode != StreamBase.OK) {
Log.e(TAG, "Player - setupStream() failed");
return errorCode;
}
} catch (PlayerBuilder.BadStateException ex) {
Log.e(TAG, "Player - BadStateException" + ex);
return StreamBase.ERROR_UNSUPPORTED;
}
}
return StreamBase.OK;
}
public int start() {
int result = StreamBase.OK;
if (mRecorder != null && (result = mRecorder.startStream()) != StreamBase.OK) {
return result;
}
if (mPlayer != null && (result = mPlayer.startStream()) != StreamBase.OK) {
return result;
}
return result;
}
public int stop() {
int playerResult = StreamBase.OK;
if (mPlayer != null) {
int result1 = mPlayer.stopStream();
int result2 = mPlayer.teardownStream();
playerResult = result1 != StreamBase.OK ? result1 : result2;
}
int recorderResult = StreamBase.OK;
if (mRecorder != null) {
int result1 = mRecorder.stopStream();
int result2 = mRecorder.teardownStream();
recorderResult = result1 != StreamBase.OK ? result1 : result2;
}
return playerResult != StreamBase.OK ? playerResult: recorderResult;
}
public int getNumPlayerBufferFrames() {
return mPlayer != null ? mPlayer.getNumBufferFrames() : 0;
}
public int getNumRecorderBufferFrames() {
return mRecorder != null ? mRecorder.getNumBufferFrames() : 0;
}
}