0

私の質問の次の繰り返し:

ご意見ありがとうございます。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 は inputSamples に 2048 を返します (1024 の FRAME_LEN に対して Wav ファイルに 2 つのチャネルがあるため、これはロジックです)。したがって、私の理解が正しければ、私のアプリケーションでは 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;
}

出力データが (RAW AAC として) .acc ファイルにダンプされると、アプリケーション mp4muxer.exe を使用して .mp4 ファイルを作成し、最終的に変換されたサウンドを聴きます。ただ、音は全然ダメ…

私が見ていない、または理解していないことがあるのだろうかと思っています。

有益なご意見をお寄せいただきありがとうございます。

4

2 に答える 2

0

サンプルをfaacEncEncodeエンコードするための各呼び出しは、1 つだけではありません。inputSamplesメイン ループは、WAV ファイルから入力バッファーに多くのサンプルを読み取り、faacEncEncodeそのバッファーを 1 回呼び出し、最後に出力バッファーを AAC ファイルに書き込む必要があります。

于 2011-03-13T22:12:01.617 に答える
0

あなたがしていることを私が誤解している可能性があります(もしそうなら、知っておくと便利です:(1)OpenFileあなたが呼び出している関数は何ですか、そしてそれは(その名前にもかかわらず)実際にファイルを開くだけでなく読み取りますか(2) どのようにinputBuffer設定されていますか?) しかし:

faacEncEncodeフレーム全体に相当するサンプルが与えられることを期待しています。フレームとは、inputSamplesを呼び出したときに返されたサンプルの数ですfaacEncOpen。(もちろん、入力の最後に達している場合は、フレーム全体よりも少なくすることができます。)

したがって、2 つのフレームのそれぞれで 460 バイトと 539 バイトを取得しています。それぞれの場合で 16 ビットではありません。また、入力データ ポインターが実際には毎回 1 つのサンプルだけオフセットされているように見えるため、フレームのオーバーラップがひどくなっています。(そして、それらの数が間違ってnbChunkいます。あなたが持っているフレームの数ではありません。)

于 2011-03-13T22:12:59.470 に答える