使用FAAC编码为m4a的RAW PCM数据无法识别?

时间:2011-12-03 12:22:58

标签: android c++ audio java-native-interface aac

我正在尝试通过JNI使用FAAC为我的Android应用项目启用AAC编码。一切似乎工作得很好,但编码部分是,嗯......相当奇怪。我必须承认,我不熟悉音频编程,已经搜索了几天的解决方案和答案,但还没有找到答案。

情况是,我使用MediaRecord将音频录制到RAW PCM数据中,并将文件保存到临时文件,比如“temp.pcm”。然后使用下面的代码将其编码为AAC .m4a文件。 问题是,编码文件已保存,大小看起来很好,但mPlayer或任何其他媒体播放器无法识别。播放它们会产生一些错误,例如不支持的格式。编码文件似乎有一些错误的结构。

我对此没有任何线索。以前有人试过这个吗?分享你的经验或者给我一些暗示......我对此非常绝望...... :(

编辑1:只是想,如下面的代码,我实际上是获取m4a文件的原始数据,但是没有标题或其他结构,以至于玩家无法识别它?

java部分:

jint Java_com_phonegap_plugins_cjplugs_CJPlugs_JNIconvPCM2FAAC(
    JNIEnv* env,
    jobject thiz, 
    jstring inputPath, 
    jstring outputPath  )
{
    const char *inFile = (*env)->GetStringUTFChars(env, inputPath, NULL);
    const char *outFile = (*env)->GetStringUTFChars(env, outputPath, NULL);

    return cppJNIconvPCM2FAAC(inFile, outFile);
}

C ++中的实际JNI部分与另一个包装文件桥接:

#include <cerrno>
#include <cstddef>

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <math.h>

#include "ipaws.h"
#include "faac.h"

int cppJNIconvPCM2FAAC(
    const char *inputPath, 
    const char *outputPath  )
{
    unsigned long faacInputSamples;
    unsigned long faacMaxOutputBytes;

    faacEncHandle faac = faacEncOpen(16000, 1, &faacInputSamples, &faacMaxOutputBytes);
    if ( !faac ) {
        return 0;
    }

    faacEncConfigurationPtr faacConfig = faacEncGetCurrentConfiguration(faac);

    faacConfig->mpegVersion   = MPEG4;
//  faacConfig->aacObjectType = MAIN;
    faacConfig->aacObjectType = LOW;
    faacConfig->allowMidside  = 0;
    faacConfig->useLfe        = 0;
    faacConfig->useTns        = 0;
    faacConfig->bitRate       = 16000; // per channel
//  faacConfig->quantqual     = 100;
    faacConfig->outputFormat  = 0;  // Raw
    faacConfig->inputFormat   = FAAC_INPUT_16BIT;
    faacConfig->bandWidth     = 0;

    if ( !faacEncSetConfiguration(faac, faacConfig) ) {
        return -1;
    }

    FILE* fd = fopen(inputPath, "rb");
    if ( fd == NULL ) {
        return -2;
    }
    FILE* fdout = fopen(outputPath, "wb+");
    if ( fdout == NULL ) {
        return -3;
    }

    char* bufSrc = new char[faacInputSamples*2];    // 每个采样16位PCM,2字节
    char* bufDst = new char[faacMaxOutputBytes];

    while ( 1 ) {
        int read = fread( bufSrc, faacInputSamples, 2, fd );
        if( read < 1 )
            break;
        int nread = faacEncEncode(faac, (int32_t *)bufSrc, (unsigned int)faacInputSamples, (unsigned char*)bufDst, faacMaxOutputBytes);

        fwrite( bufDst, nread, 1, fdout );
    }

    fclose( fdout );
    fclose( fd );
    delete[] bufSrc;
    delete[] bufDst;

    faacEncClose( faac );

    return 1;
}

1 个答案:

答案 0 :(得分:0)

你的程序没有错。但是你配置输出格式是RAW所以outfile是无头的。你必须配置outfile是 faacConfig-&gt; outputFormat = 1; 然后你可以使用FAAD2来解码文件!