You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
	
	
		
			124 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C++
		
	
		
		
			
		
	
	
			124 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C++
		
	
| 
											10 years ago
										 | #include "MicrophoneReader.h"
 | ||
|  | #include "SampleRateUtil.h"
 | ||
|  | 
 | ||
|  | #include <jni.h>
 | ||
|  | 
 | ||
|  | #include <android/log.h>
 | ||
|  | 
 | ||
|  | #define TAG "MicrophoneReader"
 | ||
|  | 
 | ||
|  | #ifndef SL_ANDROID_RECORDING_PRESET_VOICE_COMMUNICATION
 | ||
|  | #define SL_ANDROID_RECORDING_PRESET_VOICE_COMMUNICATION ((SLuint32) 0x00000004)
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | MicrophoneReader::MicrophoneReader(int androidSdkVersion, AudioCodec &audioCodec, RtpAudioSender &rtpAudioSender, Clock &clock) : | ||
|  |   androidSdkVersion(androidSdkVersion), muteEnabled(0), | ||
|  |   audioCodec(audioCodec), rtpAudioSender(rtpAudioSender), clock(clock), | ||
|  |   recorderObject(NULL), recorderRecord(NULL), recorderBufferQueue(NULL) | ||
|  | { | ||
|  | } | ||
|  | 
 | ||
|  | MicrophoneReader::~MicrophoneReader() { | ||
|  | } | ||
|  | 
 | ||
|  | void MicrophoneReader::recorderCallback(SLAndroidSimpleBufferQueueItf bufferQueue, void *context) { | ||
|  |   MicrophoneReader* microphoneReader = static_cast<MicrophoneReader*>(context); | ||
|  |   microphoneReader->recorderCallback(bufferQueue); | ||
|  | } | ||
|  | 
 | ||
|  | void MicrophoneReader::recorderCallback(SLAndroidSimpleBufferQueueItf bufferQueue) | ||
|  | { | ||
|  |   if (muteEnabled) { | ||
|  |     memset(inputBuffer, 0, FRAME_SIZE * 2 * sizeof(short)); | ||
|  |   } | ||
|  | 
 | ||
|  |   int encodedAudioLen = audioCodec.encode(inputBuffer, encodedAudio, sizeof(encodedAudio)); | ||
|  |   encodedAudioLen += audioCodec.encode(inputBuffer + FRAME_SIZE, encodedAudio + encodedAudioLen, sizeof(encodedAudio) - encodedAudioLen); | ||
|  | 
 | ||
|  |   rtpAudioSender.send(clock.tick(2), encodedAudio, encodedAudioLen); | ||
|  | 
 | ||
|  |   (*bufferQueue)->Enqueue(bufferQueue, inputBuffer, FRAME_SIZE * 2 * sizeof(short)); | ||
|  | } | ||
|  | 
 | ||
|  | void MicrophoneReader::setMute(int muteEnabled) { | ||
|  |   this->muteEnabled = muteEnabled; | ||
|  | } | ||
|  | 
 | ||
|  | int MicrophoneReader::start(SLEngineItf *engineEnginePtr) { | ||
|  |   SLEngineItf engineEngine = *engineEnginePtr; | ||
|  | 
 | ||
|  |   SLDataLocator_AndroidSimpleBufferQueue loc_bq     = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 1}; | ||
|  |   SLDataFormat_PCM                       format_pcm = {SL_DATAFORMAT_PCM, 1, SL_SAMPLINGRATE_8, | ||
|  |                                                        SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16, | ||
|  |                                                        SL_SPEAKER_FRONT_CENTER, SL_BYTEORDER_LITTLEENDIAN}; | ||
|  | 
 | ||
|  |   SLDataLocator_IODevice loc_dev  = {SL_DATALOCATOR_IODEVICE, SL_IODEVICE_AUDIOINPUT, SL_DEFAULTDEVICEID_AUDIOINPUT, NULL}; | ||
|  | 
 | ||
|  |   SLDataSource audioSrc = {&loc_dev, NULL}; | ||
|  |   SLDataSink   audioSnk = {&loc_bq, &format_pcm}; | ||
|  | 
 | ||
|  |   const SLInterfaceID id[2]  = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE, SL_IID_ANDROIDCONFIGURATION}; | ||
|  |   const SLboolean     req[2] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE}; | ||
|  | 
 | ||
|  |   if ((*engineEngine)->CreateAudioRecorder(engineEngine, &recorderObject, &audioSrc, | ||
|  |                                            &audioSnk, 2, id, req) != SL_RESULT_SUCCESS) | ||
|  |   { | ||
|  |     return -1; | ||
|  |   } | ||
|  | 
 | ||
|  |   if ((*recorderObject)->GetInterface(recorderObject, SL_IID_ANDROIDCONFIGURATION, &androidConfig) == SL_RESULT_SUCCESS) { | ||
|  |     SLint32 recordingPreset = SL_ANDROID_RECORDING_PRESET_GENERIC; | ||
|  | 
 | ||
|  |     if (androidSdkVersion >= 14) { | ||
|  |        __android_log_print(ANDROID_LOG_WARN, TAG, "Using voice communication Microphone preset..."); | ||
|  |       recordingPreset = SL_ANDROID_RECORDING_PRESET_VOICE_COMMUNICATION; | ||
|  |     } | ||
|  | 
 | ||
|  |     (*androidConfig)->SetConfiguration(androidConfig, SL_ANDROID_KEY_RECORDING_PRESET, | ||
|  |                                        &recordingPreset, sizeof(SLint32)); | ||
|  |   } | ||
|  | 
 | ||
|  |   if ((*recorderObject)->Realize(recorderObject, SL_BOOLEAN_FALSE) != SL_RESULT_SUCCESS) { | ||
|  |     return -1; | ||
|  |   } | ||
|  | 
 | ||
|  |   if ((*recorderObject)->GetInterface(recorderObject, SL_IID_RECORD, &recorderRecord) != SL_RESULT_SUCCESS) { | ||
|  |     return -1; | ||
|  |   } | ||
|  | 
 | ||
|  |   if ((*recorderObject)->GetInterface(recorderObject, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &recorderBufferQueue) != SL_RESULT_SUCCESS) { | ||
|  |     return -1; | ||
|  |   } | ||
|  | 
 | ||
|  |   if ((*recorderBufferQueue)->RegisterCallback(recorderBufferQueue, &MicrophoneReader::recorderCallback, this) != SL_RESULT_SUCCESS) { | ||
|  |     return -1; | ||
|  |   } | ||
|  | 
 | ||
|  |   if ((*recorderBufferQueue)->Enqueue(recorderBufferQueue, inputBuffer, FRAME_SIZE * 2 * sizeof(short)) != SL_RESULT_SUCCESS) { | ||
|  |     return -1; | ||
|  |   } | ||
|  | 
 | ||
|  |   if ((*recorderRecord)->SetRecordState(recorderRecord, SL_RECORDSTATE_RECORDING) != SL_RESULT_SUCCESS) { | ||
|  |     return -1; | ||
|  |   } | ||
|  | 
 | ||
|  |   return 0; | ||
|  | } | ||
|  | 
 | ||
|  | void MicrophoneReader::stop() { | ||
|  |   if (recorderRecord != NULL) { | ||
|  |     (*recorderRecord)->SetRecordState(recorderRecord, SL_RECORDSTATE_STOPPED); | ||
|  |   } | ||
|  | 
 | ||
|  |   if (recorderBufferQueue != NULL) { | ||
|  |     (*recorderBufferQueue)->Clear(recorderBufferQueue); | ||
|  |   } | ||
|  | 
 | ||
|  |   if (recorderObject != NULL) { | ||
|  |     (*recorderObject)->Destroy(recorderObject); | ||
|  | 
 | ||
|  |     recorderRecord      = NULL; | ||
|  |     recorderObject      = NULL; | ||
|  |     recorderBufferQueue = NULL; | ||
|  |   } | ||
|  | } |