毎度、いかおです
前回の続きで倍速再生について、特に音声の切り詰めかたを考えてみた。
・音声をある一定の長さできる
・それをつなげる
・のりしろを作る
まずは、これを図にしてみました
1番上が元の波形(だと思って!)で、矢印がついてる部分がサンプル対象です。
2番めはサンプル対象をくっつけた図。オレンジの線はその間のサンプル
3番めはのりしろをフェードアウト/フェードインしたところです。ここで赤い線の様になってショックノイズを低減させます
【フェードイン/アウト コード例】
#define NORISHIRO 100 // 例えばのりしろは100個
.
.
.
// 音声デコードがされたら
avcodec_decode_audio4(audioCodecCtx, decodedAudio, &decodedSize, &packet);
if (decodedSize > 0){
    size_t packetSize;
    // flgならsample出す
    if(flg){
        // m_sampleCount のりしろ長さ
        packetSize = decodedAudio->nb_samples * sizeof(short) * CHANNEL;
        short *samp = (short *)decodedAudio->data[0];
        flg = false;
        // サンプルの中に左右交互にデータがある(プラナーでない)
        for(int i=0;i < m_sampleCount;i++){
            samp[(i * 2)] = (short)(((float)m_bef[(i * 2)] * (((float)m_sampleCount - (float)i - 1.0f) / (float)m_sampleCount)) +
            ((float)samp[(i * 2)] * (((float)i + 1 ) / (float)m_sampleCount)));
            samp[(i * 2) + 1] = (short)(((float)m_bef[(i * 2) + 1] * (((float)m_sampleCount - (float)i - 1.0f) / (float)m_sampleCount)) +
           ((float)samp[(i * 2) + 1] * (((float)i + 1 ) / (float)m_sampleCount)));
        }
        // ここが再生データ
        decodedAudio->data[0];
        // これが再生データの長さ
        packetSize;
    } else {
        // ! flgならsample保存(フェードアウトに利用)
        if(decodedAudio->nb_samples > NORISHIRO){
            m_sampleCount = NORISHIRO;
        } else {
            m_sampleCount = decodedAudio->nb_samples;
        }
        memcpy((char *)m_bef, (char *)decodedAudio->data[0], m_sampleCount * sizeof(short) * 2);
        flg = true;
    }
}
.
.
.
ひとまずはこれでさほどノイズが気にならなくなりました。
1度に採れるサンプル数にもよりますが、のりしろは長くとった方がキレイに再生できます







