简体   繁体   中英

How to play two channel wav file with OpenSLES on Android in C++?

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:

    1. Use of deprecated calls which might not have well debugged code on the unknown device (test on another brand or Emulator).

    2. 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM