How to use AAudio (or other C++ layer tools recommended?) to play wav files in my android app?

Basic Info and Questions##

I was trying to play .wav files in my pure C++ Android app. Gpt recommended AAudio. And I wrote some code, but it didn’t work. Could someone help me to figure out why my code didn’t work properly?

info of wav file

I used mediainfo generated.wav, it gave these info of .wav file I was to play.

General
Complete name                            : generated.wav
Format                                   : Wave
Format settings                          : PcmWaveformat
File size                                : 19.5 KiB
Duration                                 : 624 ms
Overall bit rate mode                    : Constant
Overall bit rate                         : 257 kb/s

Audio
Format                                   : PCM
Format settings                          : Little / Signed
Codec ID                                 : 1
Duration                                 : 624 ms
Bit rate mode                            : Constant
Bit rate                                 : 256 kb/s
Channel(s)                               : 1 channel
Sampling rate                            : 16.0 kHz
Bit depth                                : 16 bits
Stream size                              : 19.5 KiB (100%)

Code

I used JNI, and here is the part about playing:

extern "C"
JNIEXPORT void JNICALL
Java_com_example_demojavacpp_MainActivity_playAudioFromFile(JNIEnv *env, jobject thiz, jstring filePath) {
    const char* filename = env->GetStringUTFChars(filePath, 0);

    // Open the WAV file
    FILE* file = fopen(filename, "rb");
    if (file == nullptr) {
        __android_log_print(ANDROID_LOG_ERROR, "TTS", "Failed to open file: %s", filename);
        env->ReleaseStringUTFChars(filePath, filename);
        return;
    }else{
        __android_log_print(ANDROID_LOG_INFO, "TTS", "Open file: %s", filename);
    }

    // Read WAV header (skip for now, you can check it if necessary)
    unsigned char header[44];
    fread(header, sizeof(unsigned char), 44, file);  // Typical WAV header size

    // Read the audio data (after header)
    fseek(file, 0, SEEK_END);
    size_t fileSize = ftell(file);
    fseek(file, 44, SEEK_SET);  // Skip header
    size_t dataSize = fileSize - 44;
    float * audioData = new float [dataSize];
    fread(audioData, sizeof(unsigned char), dataSize, file);
    fclose(file);

    // Initialize AAudio player
    AAudioPlayer player;
    if (!player.initialize(16000, 1)) {  // Set sample rate (44100 Hz for example) and channels (1 for mono)
        __android_log_print(ANDROID_LOG_ERROR, "AAUDIO", "Failed to initialize AAudio player.");
        delete[] audioData;  // Clean up the allocated memory
        env->ReleaseStringUTFChars(filePath, filename);
        return;
    }

    // Play the audio
    if (!player.playAudio(audioData, dataSize / sizeof(float))) {
        __android_log_print(ANDROID_LOG_ERROR, "AAUDIO", "Failed to play audio.");
    } else {
        __android_log_print(ANDROID_LOG_INFO, "AAUDIO", "Audio is playing.");
    }

    // Clean up
    delete[] audioData;  // Free the allocated memory for audio data
    env->ReleaseStringUTFChars(filePath, filename);
}

And here are the main two functions of AAudio: AAudioPlayer::initialize and AAudioPlayer::playAudio

bool AAudioPlayer::initialize(int sampleRate, int channelCount) {
    aaudio_result_t result;

    // Create an AAudio stream builder
    result = AAudio_createStreamBuilder(&builder);
    if (result != AAUDIO_OK) {
        LOGE("Failed to create AAudio stream builder");
        return false;
    }

    // Set format, sample rate, and channel count
    AAudioStreamBuilder_setFormat(builder, AAUDIO_FORMAT_PCM_FLOAT);
    AAudioStreamBuilder_setChannelCount(builder, channelCount);
    AAudioStreamBuilder_setSampleRate(builder, sampleRate);

    // Create the AAudio stream
    result = AAudioStreamBuilder_openStream(builder, &stream);
    if (result != AAUDIO_OK) {
        LOGE("Failed to create AAudio stream");
        return false;
    }

    return true;
}


bool AAudioPlayer::playAudio(const float * audioData, size_t numFrames) {
    aaudio_result_t result;

    // Allocate buffer
    bufferSize = numFrames;
    buffer = new float[bufferSize];
    memcpy(buffer, audioData, numFrames * sizeof(float));

    // Start the audio stream
    result = AAudioStream_requestStart(stream);
    if (result != AAUDIO_OK) {
        LOGE("Failed to start AAudio stream");
        aaudio_stream_state_t state = AAudioStream_getState(stream);
        __android_log_print(ANDROID_LOG_ERROR, "TTS", "Audio stream state: %d", state);
        return false;
    }

    // Write data to the stream
    result = AAudioStream_write(stream, buffer, bufferSize, 0);
    if (result != AAUDIO_OK) {
        LOGE("Failed to write audio data to stream");
        aaudio_stream_state_t state = AAudioStream_getState(stream);
        __android_log_print(ANDROID_LOG_ERROR, "TTS", "Audio stream state: %d", state);
        return false;
    }

    return true;
}

Results

When I ran my app, catlog showed:

1

Here’s a couple of suggestions:

  1. Looks like your audio samples are 16-bit signed integers but you are are handling them as if they were floating-point numbers. So, you should use AAUDIO_FORMAT_PCM_I16 instead of AAUDIO_FORMAT_PCM_FLOAT.

  2. You are trying to play the whole audio file in one piece. But the audio stream has an internal buffer which is usually smaller than the audio file size. Instead, you should use AMediaExtractor to read fixed-sized buffers from the audio source and write them to the stream.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa

How to use AAudio (or other C++ layer tools recommended?) to play wav files in my android app?

Basic Info and Questions##

I was trying to play .wav files in my pure C++ Android app. Gpt recommended AAudio. And I wrote some code, but it didn’t work. Could someone help me to figure out why my code didn’t work properly?

info of wav file

I used mediainfo generated.wav, it gave these info of .wav file I was to play.

General
Complete name                            : generated.wav
Format                                   : Wave
Format settings                          : PcmWaveformat
File size                                : 19.5 KiB
Duration                                 : 624 ms
Overall bit rate mode                    : Constant
Overall bit rate                         : 257 kb/s

Audio
Format                                   : PCM
Format settings                          : Little / Signed
Codec ID                                 : 1
Duration                                 : 624 ms
Bit rate mode                            : Constant
Bit rate                                 : 256 kb/s
Channel(s)                               : 1 channel
Sampling rate                            : 16.0 kHz
Bit depth                                : 16 bits
Stream size                              : 19.5 KiB (100%)

Code

I used JNI, and here is the part about playing:

extern "C"
JNIEXPORT void JNICALL
Java_com_example_demojavacpp_MainActivity_playAudioFromFile(JNIEnv *env, jobject thiz, jstring filePath) {
    const char* filename = env->GetStringUTFChars(filePath, 0);

    // Open the WAV file
    FILE* file = fopen(filename, "rb");
    if (file == nullptr) {
        __android_log_print(ANDROID_LOG_ERROR, "TTS", "Failed to open file: %s", filename);
        env->ReleaseStringUTFChars(filePath, filename);
        return;
    }else{
        __android_log_print(ANDROID_LOG_INFO, "TTS", "Open file: %s", filename);
    }

    // Read WAV header (skip for now, you can check it if necessary)
    unsigned char header[44];
    fread(header, sizeof(unsigned char), 44, file);  // Typical WAV header size

    // Read the audio data (after header)
    fseek(file, 0, SEEK_END);
    size_t fileSize = ftell(file);
    fseek(file, 44, SEEK_SET);  // Skip header
    size_t dataSize = fileSize - 44;
    float * audioData = new float [dataSize];
    fread(audioData, sizeof(unsigned char), dataSize, file);
    fclose(file);

    // Initialize AAudio player
    AAudioPlayer player;
    if (!player.initialize(16000, 1)) {  // Set sample rate (44100 Hz for example) and channels (1 for mono)
        __android_log_print(ANDROID_LOG_ERROR, "AAUDIO", "Failed to initialize AAudio player.");
        delete[] audioData;  // Clean up the allocated memory
        env->ReleaseStringUTFChars(filePath, filename);
        return;
    }

    // Play the audio
    if (!player.playAudio(audioData, dataSize / sizeof(float))) {
        __android_log_print(ANDROID_LOG_ERROR, "AAUDIO", "Failed to play audio.");
    } else {
        __android_log_print(ANDROID_LOG_INFO, "AAUDIO", "Audio is playing.");
    }

    // Clean up
    delete[] audioData;  // Free the allocated memory for audio data
    env->ReleaseStringUTFChars(filePath, filename);
}

And here are the main two functions of AAudio: AAudioPlayer::initialize and AAudioPlayer::playAudio

bool AAudioPlayer::initialize(int sampleRate, int channelCount) {
    aaudio_result_t result;

    // Create an AAudio stream builder
    result = AAudio_createStreamBuilder(&builder);
    if (result != AAUDIO_OK) {
        LOGE("Failed to create AAudio stream builder");
        return false;
    }

    // Set format, sample rate, and channel count
    AAudioStreamBuilder_setFormat(builder, AAUDIO_FORMAT_PCM_FLOAT);
    AAudioStreamBuilder_setChannelCount(builder, channelCount);
    AAudioStreamBuilder_setSampleRate(builder, sampleRate);

    // Create the AAudio stream
    result = AAudioStreamBuilder_openStream(builder, &stream);
    if (result != AAUDIO_OK) {
        LOGE("Failed to create AAudio stream");
        return false;
    }

    return true;
}


bool AAudioPlayer::playAudio(const float * audioData, size_t numFrames) {
    aaudio_result_t result;

    // Allocate buffer
    bufferSize = numFrames;
    buffer = new float[bufferSize];
    memcpy(buffer, audioData, numFrames * sizeof(float));

    // Start the audio stream
    result = AAudioStream_requestStart(stream);
    if (result != AAUDIO_OK) {
        LOGE("Failed to start AAudio stream");
        aaudio_stream_state_t state = AAudioStream_getState(stream);
        __android_log_print(ANDROID_LOG_ERROR, "TTS", "Audio stream state: %d", state);
        return false;
    }

    // Write data to the stream
    result = AAudioStream_write(stream, buffer, bufferSize, 0);
    if (result != AAUDIO_OK) {
        LOGE("Failed to write audio data to stream");
        aaudio_stream_state_t state = AAudioStream_getState(stream);
        __android_log_print(ANDROID_LOG_ERROR, "TTS", "Audio stream state: %d", state);
        return false;
    }

    return true;
}

Results

When I ran my app, catlog showed:

1

Here’s a couple of suggestions:

  1. Looks like your audio samples are 16-bit signed integers but you are are handling them as if they were floating-point numbers. So, you should use AAUDIO_FORMAT_PCM_I16 instead of AAUDIO_FORMAT_PCM_FLOAT.

  2. You are trying to play the whole audio file in one piece. But the audio stream has an internal buffer which is usually smaller than the audio file size. Instead, you should use AMediaExtractor to read fixed-sized buffers from the audio source and write them to the stream.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật