簡體   English   中英

C ++ FFmpeg音調問題

[英]C++ FFmpeg pitch issue

我正在使用swr_convert降低/提高傳入音頻的音調並將其存儲在.mp3中。 為了改變音高,我將采樣率除以一個因子。 但是,當此因素不是1時,產生的音頻會稍微失真。這是我的轉換代碼:

...

// Set up resample context
swrContext = swr_alloc();
if (!swrContext)
    throw -15;

av_opt_set_int(swrContext, "in_channel_count", codecContext->channels, 0);
av_opt_set_int(swrContext, "in_channel_layout", codecContext->channel_layout, 0);
av_opt_set_int(swrContext, "in_sample_rate", codecContext->sample_rate, 0);
av_opt_set_sample_fmt(swrContext, "in_sample_fmt", codecContext->sample_fmt, 0);

av_opt_set_int(swrContext, "out_channel_count", STREAM_AUDIO_CHANNELS, 0);
av_opt_set_int(swrContext, "out_channel_layout", STREAM_AUDIO_CHANNEL_LAYOUT, 0);
av_opt_set_int(swrContext, "out_sample_rate", STREAM_AUDIO_SAMPLE_RATE / pitch, 0);
av_opt_set_sample_fmt(swrContext, "out_sample_fmt", STREAM_AUDIO_SAMPLE_FORMAT_GM, 0);

if (swr_init(swrContext))
    throw -16;

// Allocate re-usable frame
frameDecoded = av_frame_alloc();
if (!frameDecoded)
    throw -17;

frameDecoded->format = codecContext->sample_fmt;
frameDecoded->channel_layout = codecContext->channel_layout;
frameDecoded->channels = codecContext->channels;
frameDecoded->sample_rate = codecContext->sample_rate;

// Load frames
inPacket.data = NULL;
inPacket.size = 0;

int gotFrame, samples = 0;

while (av_read_frame(formatContext, &inPacket) >= 0) {

    if (inPacket.stream_index != streamId) 
        continue;

    if (avcodec_decode_audio4(codecContext, frameDecoded, &gotFrame, &inPacket) < 0)
        throw -18;

    if (!gotFrame)
        continue;

    // Begin conversion
    if (swr_convert(swrContext, NULL, 0, (const uint8_t **)frameDecoded->data, frameDecoded->nb_samples) < 0)
        throw -19;

    while (swr_get_out_samples(swrContext, 0) >= RAW_AUDIO_FRAME_SIZE) {

        // Allocate data
        uint8_t **convertedData = NULL;
        if (av_samples_alloc_array_and_samples(&convertedData, NULL, STREAM_AUDIO_CHANNELS, RAW_AUDIO_FRAME_SIZE, STREAM_AUDIO_SAMPLE_FORMAT_GM, 0) < 0)
            throw -20;

        // Convert
        if (swr_convert(swrContext, convertedData, RAW_AUDIO_FRAME_SIZE, NULL, 0) < 0)
            throw -21;

        // Calculate buffer size
        size_t bufferSize = av_samples_get_buffer_size(NULL, STREAM_AUDIO_CHANNELS, RAW_AUDIO_FRAME_SIZE, STREAM_AUDIO_SAMPLE_FORMAT_GM, 0);
        if (bufferSize < 0)
            throw -22;

        fwrite(convertedData[0], 1, bufferSize, outStream);
        av_free(convertedData);
    }
}

...

STREAM_AUDIO_SAMPLE_RATE定義為44100。如果有幫助,請參見下面的整個程序: http ://pastebin.com/5akEwNg4

該程序將生成一個帶有25個音調減小的.mp3。 這是失真的示例: http : //www.stuffbydavid.com/dl/30256478.mp3

您能發現關於我的轉換的任何錯誤信息,還是我更改音高的方法不正確? 還有另一種方法嗎?

調用swr_convert()並以NULL作為輸入將刷新內部隊列,並(間接)導致變形(因為刷新后您提交了新輸入)。 您需要,直到該文件已完成解碼, 然后才在最后刷新隊列與NULL輸入回路與有效輸入輸出緩沖(均為非NULL)調用swr_convert。

暫無
暫無

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

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