簡體   English   中英

收集來自libav的解碼音頻成倍

[英]Collect decoded audio from libav as doubles

我目前正在嘗試收集解碼的音頻數據(來自多種格式)以執行某些音頻操作(使用* .wav文件進行測試)。

我有一個通過FFmpeg libav處理所有解碼的類。 如果我將數據作為unit8_t提取到向量中,並且

for (int i = 0; i < bytevector.size(); i++) {
    fwrite(&bytevector[i], sizeof (uint8_t), 1, outfile2);
}

到原始文件並通過play -t raw -r 44100 -b16 -c 1 -e signed sound.raw它聽起來很不錯。

但是,當文件為每個樣本2個字節並且frame->data信息指定為uint8_t時,如何將所有正確的信息加倍? 我測試過的wav文件是44100 / 16bits / 1通道。 (我已經有將uint8_t *更改為double的代碼)

使用Scilab打開相同的文件將顯示字節向量大小的一半為兩倍。

Scilab中的wav文件以雙精度數組形式顯示:
-0.1,-0.099,-0.098,...,0.099,+ 0.1

與字節向量:
51、243、84、243、117、243,...

51和243真的可以構成雙倍嗎? 關於如何解決這個問題有什么建議嗎?

以下代碼供參考:

 while ((av_read_frame(formatContext, &readingPacket)) == 0) {
        if (readingPacket.stream_index == audioStreamIdx) {
            AVPacket decodingPacket = readingPacket;

            while (decodingPacket.size > 0) {
                int gotFrame = 0;
                int result = avcodec_decode_audio4(context, frame, &gotFrame, &decodingPacket);

                if (result < 0) {
                    break;
                }

                decoded = FFMIN(result, decodingPacket.size);

                if (gotFrame) {
                    data_size = (av_get_bytes_per_sample(context->sample_fmt));
                    if (data_size < 0) {
                    }

                    // Only for 1 channel temporarily
                    for (int i = 0; i < frame->nb_samples; i++) {
                        for (int ch = 0; ch < context->channels; ch++) {
                            for (int j = 0; j < data_size; j++) {
                                bytevector.push_back(*(frame->data[ch] + data_size * i + j)); 
                            }
                        }
                    }
                } else {
                    decodingPacket.size = 0;
                    decodingPacket.data = NULL;
                }
                decodingPacket.size -= result;
                decodingPacket.data += result;
            }
        }
        av_free_packet(&readingPacket);
    }

兩個字節轉換為浮點數的快速方法:

byte bits[] = {195,255}; //first sample in the test s16 wav file
int16_t sample;
memcpy(&sample,&bits,sizeof(bits));
std::cout<<sample*(1.0f/32768.0f)<<std::endl;

打印時(更精確的-0.001861572265625 (xx);),此代碼產生-0.001861572265625 ,這是Scilab使用相同文件給出的第一個數字。

希望這對遇到類似問題的人有所幫助。

音頻數據以許多不同的格式存儲。 獲得uint8_t[]數組的意義很小。 不是每個數組一個字節。 相反,您需要知道格式。 這里-b16告訴我uint8_t[]數據實際上是16位PCM編碼的數據,即從-32768到+32767的范圍。 Scilab似乎更喜歡浮點刻度,因此可以除以32768.0。 那只是表象的改變。 只是將比例縮小為-1.0,+ 1.0。

將其與角度進行比較:pi / 2弧度上的直角為90度; 確切的數字無關緊要,但是兩者都是一個完整圓的1/4。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM