毎度、いかおです
前回の続きで倍速再生について、特に音声の切り詰めかたを考えてみた。
・音声をある一定の長さできる
・それをつなげる
・のりしろを作る
まずは、これを図にしてみました
1番上が元の波形(だと思って!)で、矢印がついてる部分がサンプル対象です。
2番めはサンプル対象をくっつけた図。オレンジの線はその間のサンプル
3番めはのりしろをフェードアウト/フェードインしたところです。ここで赤い線の様になってショックノイズを低減させます
【フェードイン/アウト コード例】
#define NORISHIRO 100 // 例えばのりしろは100個 . . . // 音声デコードがされたら avcodec_decode_audio4(audioCodecCtx, decodedAudio, &amp;amp;decodedSize, &amp;amp;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度に採れるサンプル数にもよりますが、のりしろは長くとった方がキレイに再生できます