毎度、いかおです
前回の続きで倍速再生について、特に音声の切り詰めかたを考えてみた。
・音声をある一定の長さできる
・それをつなげる
・のりしろを作る
まずは、これを図にしてみました
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度に採れるサンプル数にもよりますが、のりしろは長くとった方がキレイに再生できます






