You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Native C++使用AudioRecord类录制音频后PCM文件无声问题求助

Question: Native Android AudioRecord produces PCM file with no sound in Cool Edit Pro

I implemented audio recording using Android's AudioRecord class in Native C++, compiled the executable, pushed it to /data on my device, and ran it. The PCM file is generated successfully, but when I try to play it with Cool Pro Edit, there's no sound. Can anyone help me troubleshoot this issue?

Here's my code:

#include<stdio.h>
#include<stdlib.h>
#include <media/AudioRecord.h>
using namespace android;
//==============================================
// Audio Record Defination
//==============================================
static pthread_t g_AudioRecordThread;
static pthread_t * g_AudioRecordThreadPtr = NULL;
volatile bool g_bQuitAudioRecordThread = false;
volatile int g_iInSampleTime = 0;
int g_iNotificationPeriodInFrames = 8000/10; // g_iNotificationPeriodInFrames should be change when sample rate changes.
static void * AudioRecordThread( void *inArg );
void AudioRecordCallback(int event, void* user, void *info) {
    if(event == android::AudioRecord::EVENT_NEW_POS) {
        g_iInSampleTime += g_iNotificationPeriodInFrames;
        //if(g_iInSampleTime > g_iNotificationPeriodInFrames*100)
        // g_bQuitAudioRecordThread = true;
    } else if (event == android::AudioRecord::EVENT_MORE_DATA) {
        android::AudioRecord::Buffer* pBuff = (android::AudioRecord::Buffer*)info;
        pBuff->size = 0;
    } else if (event == android::AudioRecord::EVENT_OVERRUN) {
        //LOGE(" EVENT_OVERRUN \n");
        printf("[%d%s]EVENT_OVERRUN \n",__LINE__,__FUNCTION__);
    }
}
static void * AudioRecordThread( void *inArg ) {
    uint64_t inHostTime = 0;
    void * inBuffer = NULL;
    audio_source_t inputSource = AUDIO_SOURCE_MIC;
    audio_format_t audioFormat = AUDIO_FORMAT_PCM_16_BIT;
    audio_channel_mask_t channelConfig = AUDIO_CHANNEL_IN_MONO; //AUDIO_CHANNEL_IN_STEREO;
    int bufferSizeInBytes = 1600;
    int sampleRateInHz = 8000;
    android::AudioRecord * pAudioRecord = NULL;
    FILE * g_pAudioRecordFile = NULL;
    //char strAudioFile[] = "/mnt/sdcard/external_sd/AudioRecordFile.pcm";
    char strAudioFile[] = "./AudioRecordFile.pcm";
    int iNbChannels = 1; // 1 channel for mono, 2 channel for streo
    int iBytesPerSample = 2; // 16bits pcm, 2Bytes
    int frameSize = 0; // frameSize = iNbChannels * iBytesPerSample
    //int minFrameCount = 0; // get from AudroRecord object
    size_t minFrameCount = 0; // get from AudroRecord object
    int iWriteDataCount = 0; // how many data are there write to file
    printf("[%d%s]thread enter ok!\n",__LINE__,__FUNCTION__);
    String16 pack_name("wang_test");
    printf("[%d%s]thread enter ok!\n",__LINE__,__FUNCTION__);
#if 1
    // log the thread id for debug info
    //LOGD("%s Thread ID = %d \n", __FUNCTION__, pthread_self());
    printf("[%d%s] Thread ID = %d \n", __LINE__,__FUNCTION__, pthread_self());
    g_iInSampleTime = 0;
    g_pAudioRecordFile = fopen(strAudioFile, "wb+");
    if(g_pAudioRecordFile == NULL) {
        printf("open file erro !\n");
    }
    iNbChannels = (channelConfig == AUDIO_CHANNEL_IN_STEREO) ? 2 : 1;
    frameSize = iNbChannels * iBytesPerSample;
    android::status_t status = android::AudioRecord::getMinFrameCount( &minFrameCount, sampleRateInHz, audioFormat, channelConfig);
    if(status != android::NO_ERROR) {
        //LOGE("%s AudioRecord.getMinFrameCount fail \n", __FUNCTION__);
        printf("[%d%s]AudioRecord.getMinFrameCount fail \n",__LINE__,__FUNCTION__);
        goto exit ;
    }
    //LOGE("sampleRateInHz = %d minFrameCount = %d iNbChannels = %d frameSize = %d ",
    // sampleRateInHz, minFrameCount, iNbChannels, frameSize);
    printf("[%d%s]sampleRateInHz = %d minFrameCount = %d iNbChannels = %d frameSize = %d \n", __LINE__,__FUNCTION__,sampleRateInHz, minFrameCount, iNbChannels, frameSize);
    bufferSizeInBytes = minFrameCount * frameSize;
    inBuffer = malloc(bufferSizeInBytes);
    if(inBuffer == NULL) {
        //LOGE("%s alloc mem failed \n", __FUNCTION__);
        printf("[%d%s] alloc mem failed \n",__LINE__, __FUNCTION__);
        goto exit ;
    }
    g_iNotificationPeriodInFrames = sampleRateInHz/10;
    pAudioRecord = new android::AudioRecord(pack_name);
    if(NULL == pAudioRecord) {
        //LOGE(" create native AudioRecord failed! ");
        printf(" [%d%s] create native AudioRecord failed! \n",__LINE__,__FUNCTION__);
        goto exit;
    }
    pAudioRecord->set( inputSource, sampleRateInHz, audioFormat, channelConfig, 0, AudioRecordCallback, NULL, 0, true);
    if(pAudioRecord->initCheck() != android::NO_ERROR) {
        //LOGE("AudioTrack initCheck error!");
        printf("[%d%s]AudioTrack initCheck error!\n",__LINE__,__FUNCTION__);
        goto exit;
    }
    if(pAudioRecord->setPositionUpdatePeriod(g_iNotificationPeriodInFrames) != android::NO_ERROR) {
        //LOGE("AudioTrack setPositionUpdatePeriod error!");
        printf("[%d%s]AudioTrack setPositionUpdatePeriod error!\n",__LINE__,__FUNCTION__);
        goto exit;
    }
    if(pAudioRecord->start()!= android::NO_ERROR) {
        //LOGE("AudioTrack start error!");
        printf("[%d%s]AudioTrack start error!\n",__LINE__,__FUNCTION__);
        goto exit;
    }
    while (!g_bQuitAudioRecordThread) {
        //inHostTime = UpTicks();
        int readLen = pAudioRecord->read(inBuffer, bufferSizeInBytes);
        int writeResult = -1;
        if(readLen > 0) {
            iWriteDataCount += readLen;
            if(NULL != g_pAudioRecordFile) {
                writeResult = fwrite(inBuffer, 1, readLen, g_pAudioRecordFile);
                if(writeResult < readLen) {
                    //LOGE("Write Audio Record Stream error");
                    printf("[%d%s]Write Audio Record Stream error\n",__LINE__,__FUNCTION__);
                }
            }
            // write PCM data to file or other stream,implement it yourself
            //writeResult = WriteAudioData(
            // g_iInSampleTime,
            // inHostTime,
            // inBuffer,
            // readLen);
            //LOGD("readLen = %d writeResult = %d iWriteDataCount = %d", readLen, writeResult, iWriteDataCount);
        } else {
            //LOGE("pAudioRecord->read readLen = 0");
            printf("[%d%s]pAudioRecord->read readLen = 0\n",__LINE__,__FUNCTION__);
        }
    }
exit:
    if(NULL != g_pAudioRecordFile) {
        fflush(g_pAudioRecordFile);
        fclose(g_pAudioRecordFile);
        g_pAudioRecordFile = NULL;
    }
    if(pAudioRecord) {
        pAudioRecord->stop();
        //delete pAudioRecord;
        pAudioRecord == NULL;
    }
    if(inBuffer) {
        free(inBuffer);
        inBuffer = NULL;
    }
#endif
    //LOGD("%s Thread ID = %d quit\n", __FUNCTION__, pthread_self());
    printf("[%d%s] Thread ID = %d quit\n", __LINE__,__FUNCTION__, pthread_self());
    return NULL;
}
int main() {
    printf("hello world! \n");
    pthread_t record_pid ;
    if(pthread_create(&record_pid,NULL,AudioRecordThread,NULL)<0) {
        printf("%d%s pthread create erro !\n",__LINE__,__FUNCTION__);
    }
    while(1) {
    }
    return 0;
}

Answer

Hey there! I’ve run into this exact issue before when debugging Native AudioRecord implementations—PCM files look like they’re generated but play silence. Let’s walk through the troubleshooting step by step:

1. First, Check Cool Edit Pro’s Import Settings (Most Common Fix!)

PCM is raw, headerless audio data—Cool Edit Pro has no way to guess your recording parameters. Your code uses these settings:

  • Sample Rate: 8000 Hz
  • Bit Depth: 16-bit
  • Channels: Mono (Single Channel)
  • Byte Order: Little Endian (Android’s default for PCM)

To import correctly:

  1. Go to File > Import > Raw Data in Cool Edit Pro
  2. Select your PCM file, then set these values in the dialog:
    • Sample Rate: 8000 Hz
    • Resolution: 16-bit
    • Channels: Mono
    • Byte Order: Little Endian
  3. Click OK and play. If you still hear nothing, move to the next step.

2. Verify the PCM File Has Actual Audio Data

If the player settings are right, confirm the file isn’t just zeros:

  • Pull the file to your computer: adb pull /data/AudioRecordFile.pcm ./
  • Check the raw bytes:
    • On Windows: certutil -dump AudioRecordFile.pcm | head -20
    • On Linux/macOS: hexdump -C AudioRecordFile.pcm | head -20
  • If you see only 00 00 00 00, no audio was recorded. If you see varying hex values, the file has data—move on to check your code.

3. Debug Your Recording Code

Looking at your code, here are key areas to check:

3.1 Microphone Permissions

Android 6.0+ requires the RECORD_AUDIO permission, even for Native apps. Verify and grant it:

  • Check permission status: adb shell dumpsys package wang_test (your app’s package name is wang_test)
  • Grant if missing: adb shell pm grant wang_test android.permission.RECORD_AUDIO
  • Restart your executable and re-record.

3.2 Fix the EVENT_MORE_DATA Callback

Your callback handles EVENT_MORE_DATA by setting pBuff->size = 0, which is problematic:

else if (event == android::AudioRecord::EVENT_MORE_DATA) {
    android::AudioRecord::Buffer* pBuff = (android::AudioRecord::Buffer*)info;
    pBuff->size = 0;
}

This event is for push-mode recording, but your code uses pull-mode (looping read() calls). Setting size=0 can disrupt the AudioRecord’s internal data flow. Just comment out this entire branch—it’s not needed for your implementation.

3.3 Check if read() is Actually Getting Data

Your code logs when readLen = 0—watch for that message when running the app. If it pops up frequently:

  • Print the AudioRecord state before reading: printf("AudioRecord State: %d\n", pAudioRecord->getState());
  • The expected state for recording is AUDIO_RECORD_STATE_RECORDING (value 3). If it’s not, your initialization failed.

3.4 Fix the Resource Leak Bug

In your exit block, you have a typo that doesn’t free the AudioRecord object:

// Wrong: This is a comparison, not assignment
pAudioRecord == NULL;

// Correct:
delete pAudioRecord;
pAudioRecord = NULL;

This won’t fix the silence issue, but it’s critical for avoiding memory leaks.

4. Test with a More Reliable Player

If Cool Edit Pro still isn’t working, use ffplay (part of FFmpeg) to test the file with explicit parameters:

ffplay -f s16le -ar 8000 -ac 1 AudioRecordFile.pcm

This command directly matches your recording settings. If you hear sound here, the problem is definitely Cool Edit Pro’s import settings. If not, go back to checking permissions and the read() logic in your code.


内容的提问来源于stack exchange,提问作者potato

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 23:37:27