I found a Google Sample that plays 1-channel audio with OpenSLES in C++. If I try to play two-channel wav-file and replace
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};
with
SLDataFormat_PCM format_pcm = {SL_DATAFORMAT_PCM, 2, SL_SAMPLINGRATE_44_1,
SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16,
SL_SPEAKER_FRONT_CENTER, SL_BYTEORDER_LITTLEENDIAN};
in the this C file , the app crashes.
Cannot figure out what else should I change? Probably AudioPlayer or OutputMix should be initialized differently for playing different format?
There is a code that calls CreateOutputMix two times to play 2-channel audio, but it looks a bit strange. Is it correct?
Two problems:
One problem I see is a comment in the OpenSLES.h file:
SLDataFormat_PCM IS DEPRECATED . Use SLDataFormat_PCM_EX instead.
/** PCM-type-based data format definition where formatType must be SL_DATAFORMAT_PCM*/
/* SLDataFormat_PCM IS DEPRECATED. Use SLDataFormat_PCM_EX instead. */
typedef struct SLDataFormat_PCM_ {
SLuint32 formatType;
SLuint32 numChannels;
SLuint32 samplesPerSec;
SLuint32 bitsPerSample;
SLuint32 containerSize;
SLuint32 channelMask;
SLuint32 endianness;
} SLDataFormat_PCM;
/** PCM-type-based data format definition where formatType must be SL_DATAFORMAT_PCM_EX*/
typedef struct SLDataFormat_PCM_EX_ {
SLuint32 formatType;
SLuint32 numChannels;
SLuint32 sampleRate;
SLuint32 bitsPerSample;
SLuint32 containerSize;
SLuint32 channelMask;
SLuint32 endianness;
SLuint32 representation;
} SLDataFormat_PCM_EX;
Second issue:
In the file you linked to: android-ndk/native-audio/app/src/main/cpp/ native-audio-jni.c
Line 297:
// configure audio source
SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2};
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};
Line 804:
// configure audio sink
SLDataLocator_AndroidSimpleBufferQueue loc_bq = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2};
SLDataFormat_PCM format_pcm = {SL_DATAFORMAT_PCM, 1, SL_SAMPLINGRATE_16,
SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16,
SL_SPEAKER_FRONT_CENTER, SL_BYTEORDER_LITTLEENDIAN};
You say changing the code to this causes a crash:
SLDataFormat_PCM format_pcm = {SL_DATAFORMAT_PCM, 2, SL_SAMPLINGRATE_44_1,
SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16,
SL_SPEAKER_FRONT_CENTER, SL_BYTEORDER_LITTLEENDIAN};
Shouldn't you use this instead:
SLDataFormat_PCM format_pcm = {SL_DATAFORMAT_PCM, 2 SL_SAMPLINGRATE_44_1,
SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16,
SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT,
SL_BYTEORDER_LITTLEENDIAN
};
Problems:
Use of deprecated calls which might not have well debugged code on the unknown device (test on another brand or Emulator).
You ought to use:
format_pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
References: Android OpenSL “pAudioSrc: data format 2 not allowed” - denying SL_DATAFORMAT_PCM?
You say; "... the app crashes.". Why not have an error handler pop up a message explaining which error was thrown after the call, after dismissing it the program should simply exit() and not "crash".
PS: I don't have a development environment setup to test your code so I can't be of more help. There are certainly enough sample implementations that have been improved to test against your device. It's certainly more difficult to offer assistance when we don't know which phone or compiler you are using to look for known bugs.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.