【问题标题】:PCM to AAC with FAAC, numberBytesWritten >> 16bits?PCM 到带有 FAAC 的 AAC,写入的字节数 >> 16 位?
【发布时间】:2023-03-15 00:46:01
【问题描述】:

我的问题的下一个迭代:

感谢您的意见,它帮助我更多地了解 Frame 和 inputSamples 实用程序。 我已经用你给我的新知识对我的源代码进行了修改。但是我仍然有问题,所以我可能没有完全理解你的意思。 这是我的 OpenFile 函数,对不起名称,但我稍后会重构;什么时候可以工作=)

//-----------------------------------------------------------------------------
/* 
This Function Open a File containing the Audio, Binary, Data.
*///___________________________________________________________________________
const short* OpenFile(const char* fileName, long& fileSize, WavFormat* wav)
{
// ouvre le fichier
ifstream file;
file.open((char*)fileName, ios::binary|ios::in);

if (file.good())
{
    // Read the WAV's Header
    wav = CheckWavHeader(file, wav);

    cout << "chunkID: " << wav->chunkID <<'\n';
    cout << "chunkSize: " << wav->chunkSize <<'\n';
    cout << "format: " << wav->format <<'\n';
    cout << "subChunk1ID: " << wav->subChunk1ID <<'\n';
    cout << "subChunk1Size: " << wav->subChunk1Size <<'\n';
    cout << "audioFormat: " << wav->audioFormat <<'\n'; // audioFormat == 1, alors PCM 16bits
    cout << "numChannels: " << wav->numChannels <<'\n';
    cout << "sampleRate: " << wav->sampleRate <<'\n';
    cout << "byteRate: " << wav->byteRate <<'\n';
    cout << "blockAlign: " << wav->blockAlign <<'\n';
    cout << "bitsPerSample: " << wav->bitsPerSample <<'\n';
    cout << "subChunk2ID: " << wav->subChunk2ID <<'\n';
    cout << "subChunk2Size: " << wav->subChunk2Size <<'\n';

    // Get the file’s size
    file.seekg(0L, ios::end);
    fileSize = ((long)file.tellg() - DATA_POS);

    file.seekg(DATA_POS, ios::beg); // back to the data.

    // Read the Data into the Buffer
    uint nbSamples = fileSize / sizeof(short);
    short* inputArray = new short[nbSamples];
    file.read((char*)inputArray, fileSize);

    // Close the file and return the Data
    file.close();
    return (const short*)inputArray;
}
else
{
    exit(-1);
}
}

我正在打开文件,检查它的大小,创建一个短缓冲区并将 wav 的数据读入短缓冲区,最后我返回它。

现在我主要评论了 G711 解码器。 当我运行应用程序时,faacEncOpen 为我提供了 2048 的 inputSamples(这是合乎逻辑的,因为我在 Wav 文件中有 2 个通道,FRAME_LEN 为 1024)。 因此,如果我理解正确,我的应用程序需要 1 帧 == 2048 个样本。因此,对于我调用 faacEncEncode 的每一帧,我都会在 inputBuffer[i * inputSamples] 索引处给出与 inputSamples 大小相同的 tmpInputBuffer。

//-----------------------------------------------------------------------------
/*
The Main entry Point of the Application
*///_____________________________________________________________________________
int main()
{
// Get the File's Data
WavFormat* wav = new WavFormat;
long fileSize;
const short* fileInput = OpenFile("audioTest.wav", fileSize, wav);

// G711 mu-Law Decoder
//MuLawDecoder* decoder = new MuLawDecoder();
//short* inputBuffer = decoder->MuLawDecode_shortArray((byte*)fileInput, (int)nbChunk);

short* inputBuffer = (short*)fileInput;

// Info for FAAC
ulong sampleRate = wav->sampleRate;
uint numChannels = wav->numChannels;
ulong inputSamples;
ulong maxOutputBytes;

// Ouvre l'Encodeur et assigne la Configuration.
faacEncHandle hEncoder = faacEncOpen(sampleRate, numChannels, &inputSamples, &maxOutputBytes);
faacEncConfigurationPtr faacConfig = faacEncGetCurrentConfiguration(hEncoder);

faacConfig->inputFormat = FAAC_INPUT_16BIT;
faacConfig->bitRate = 64000;

int result = faacEncSetConfiguration(hEncoder, faacConfig);

/*Input Buffer and Output Buffer*/
byte* outputBuffer = new byte[maxOutputBytes];
int nbBytesWritten = 0;
Sink* sink = new Sink();

uint nbFrame = fileSize / inputSamples;
int32_t* tmpInputBuffer = new int32_t[inputSamples];

for (uint i = 0; i < nbFrame; i++)
{   
    strncpy((char*)tmpInputBuffer, (const char*)&inputBuffer[i * inputSamples], inputSamples);

    nbBytesWritten = faacEncEncode(hEncoder, tmpInputBuffer, inputSamples, outputBuffer, maxOutputBytes);

    cout << 100.0 * (float)i / nbFrame << "%\t nbBytesWritten = " << nbBytesWritten << "\n";

    if (nbBytesWritten > 0)
    {
        sink->AddAACStream(outputBuffer, nbBytesWritten);
    }
}

sink->WriteToFile("output.aac");

// Close AAC Encoder
faacEncClose(hEncoder);

// Supprimer tous les pointeurs
delete sink;
//delete decoder;
delete[] fileInput;
//delete[] inputBuffer;
delete[] outputBuffer;
delete[] tmpInputBuffer;

system("pause");

return 0;
}

当输出数据转储到 .acc 文件(作为 RAW AAC)中时,我使用应用程序 mp4muxer.exe 创建一个 .mp4 文件来收听最终转换后的声音。但是声音一点都不好……

我想知道是否有一些我没有看到或不明白我应该看到的东西。

提前感谢您提供有用的意见。

【问题讨论】:

    标签: c++ encoding pcm aac


    【解决方案1】:

    faacEncEncode 的每次调用都会对inputSamples 样本进行编码,而不仅仅是一个。您的主循环应该将 WAV 文件中的许多样本读入输入缓冲区,然后为该缓冲区调用一次 faacEncEncode,最后将输出缓冲区写入 AAC 文件。

    【讨论】:

    • 你到底在用strncpy做什么?无论如何都不需要将输入数据复制到临时缓冲区中,strncpy 将在找到零值字节时停止复制,因为它旨在用于字符串,而不是二进制数据。只需使用&amp;inputBuffer[i * inputSamples] 作为faacEncode 的输入参数。
    【解决方案2】:

    我可能误解了你在做什么(如果是这样,了解一下会很有用:(1)你正在调用的 OpenFile 函数是什么,并且它(尽管它的名字)实际上是 读取文件并打开它?(2)inputBuffer是如何设置的?)但是:

    faacEncEncode 期望得到一整帧的样本。一帧是您在调用faacEncOpen 时在inputSamples 中传回的样本数。 (当然,如果你已经到达输入的末尾,你可以给它不到一整帧。)

    因此,两帧中的每一个都得到 460 和 539 字节,而不是每种情况下的 16 位。而且看起来您的输入数据指针实际上每次仅偏移一个样本,因此您处理的帧重叠严重。 (而且它们的数量错误;nbChunk 不是您拥有的帧数。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-08
      • 1970-01-01
      • 2015-04-16
      • 2014-08-18
      • 1970-01-01
      • 2013-01-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多