マイク⇒ピッチ調節⇒スピーカー
KK  2016/03/15(Tue) 19:24
プログラミング初心者です。
マイク入力した音声のピッチを変えて、
スピーカーにリアルタイムで出力したいと思い、試行錯誤しています。

下記では、ピッチは変わるのですが、音がブツブツ切れます。
マイク入力のバッファ(秒数)を短くしても効果がなく、
短すぎると再生もされなくなります。

多少、入力⇒出力に遅れがあってもいいので、
きれいに再生ができる方法がありましたら、お願いします。


# include <Siv3D.hpp>

void Main()
{
Recorder recorder;
if (!recorder.open(0, 0.5s, RecordingFormat::S44100, false))
{
return;
}
if (!recorder.start())
{
return;
}

Sound sound(recorder.getWave());
sound.setLoop(false);
sound.play();

while (System::Update())
{

//★マイク入力が一杯になったら再生バッファに転送する。
if (recorder.isEnded())
{
sound.stop();
sound.fill(recorder.getWave());
sound.play();
recorder.start();
}

Line(315, 240, 325, 240).draw(4);//横軸
Line(320, 480, 320, 0).drawArrow(4, { 20, 20 });//縦軸

const Point pos = Mouse::Pos();
Circle(pos, 20).draw(Palette::Orange);

const double pitch = -(pos.y - 240) / 80.0;
sound.changePitchSemitones(pitch);

PutText(L"pitch: {} "_fmt, pitch).from(20, 20);

}
}
記事編集
Reputeless  2016/03/16(Wed) 21:39
マイク入力の音声を直接 Sound に送るサンプルは次の通りです。

# include <Siv3D.hpp>

void Main()
{
const size_t BufferSize = 44100 * 10;

Recorder recorder(BufferSize);
recorder.start();

Sound sound(Wave(BufferSize), SoundLoop::All);

size_t readPos = 0;
size_t writePos = 0;
bool slow = false;

while (System::Update())
{
const size_t soundPos = sound.streamPosSample();

// ある程度変換後のサンプルがたまったら再生開始
if (!sound.isPlaying() && writePos > 8820)
{
sound.play();
}

if (soundPos < writePos)
{
const size_t diff = writePos - soundPos;

// この数字が小さいと、ずれは小さくなるがノイズが入りやすくなる
if (diff < 4410 && !slow)
{
// 再生が追い付いてきてバッファに余裕がなくなったら再生速度を少し落とす
sound.setSpeed(0.9);
slow = true;
}
else if(diff >=4410 && slow)
{
sound.setSpeed(1.0);
slow = false;
}
}

size_t readSize = recorder.getPosSample() - readPos;

while (readSize)
{
const size_t writeSize = Min(sound.lengthSample() - writePos, readSize);
sound.fill(writePos, &recorder.getWave()[readPos], writeSize);

writePos += writeSize;
if (writePos == BufferSize)
{
writePos = 0;
}

readPos += writeSize;
readSize -= writeSize;
}

if (recorder.isEnded())
{
readPos = 0;
recorder.start();
}

const double pitch = -(Mouse::Pos().y - 240) / 80.0;
sound.changePitchSemitones(pitch);
PutText(L"pitch: {}"_fmt, pitch).from(20, 20);
}
}
編集
KK  2016/03/18(Fri) 09:50
Reputelessさん

ありがとうございます!
ピッチ変更途中も切れることなく、再生されます。
自力開発できるように勉強していきます。

KK
編集
件名
Re: マイク⇒ピッチ調節⇒スピーカー
名前
コメント
画像添付


投稿修正キー (投稿を修正する時に使います)
画像認証 (右画像の数字を入力) 投稿キー

- WEB PATIO -