Я программирую небольшой Music Engine для своей игры на C # и XNA, и одним из аспектов этого является возможность зацикливания фрагмента песни. Например, моя песня имеет вступление, и когда песня достигла конца (или любой другой конкретной точки), она возвращается туда, где вступление только что закончилось. (A - B - B - B ...)
Сейчас я использую IrrKlank, который работает отлично, без пробелов, но у меня проблема:
Точка, где нужно прыгать назад, немного неточна. Вот пример кода:
public bool Passed(float time)
{
if ( PlayPosition >= time )
return true;
return false;
}
//somewhere else
if( song.Passed( 10.0f ) )
song.JumpTo( 5.0f );
Теперь проблема в том, что песня проходит 10 секунд, но проигрывает несколько миллисекунд до 10.1f или около того, а затем переходит на 5 секунд. Это не так драматично, но очень неправильно для моих нужд. Я попытался исправить это так:
public bool Passed( float time )
{
if( PlayPosition + 3 * dt >= time && PlayPosition <= time )
return true;
return false;
}
(dt - время дельты, время, прошедшее с последнего кадра)
Но я не думаю, что это хорошее решение для этого.
Я надеюсь, что вы можете понять мою проблему (и мой английский, yay / o /) и помочь мне :)
Ответы:
На мой взгляд, более простое и обычное решение состоит из двух разных треков: вступления и цикла. Тогда единственная проблема - определить, когда вступление заканчивается (довольно просто, хотя и не совсем точно, если использовать 30fps). Затем второй трек можно воспроизвести с включенным циклом.
Таким образом, вы уменьшаете ошибки при воспроизведении до небольшой задержки при первом запуске цикла, а не каждый раз, когда необходимо перематывать часть цикла.
источник
Идеальным решением было бы знать заранее, какие части песни должны быть загружены рядом в буфер. Каждый «раздел» A-B-C будет иметь время начала и окончания, и это будет ваша потоковая система более низкого уровня, которая будет загружать правильные части файла в правильном порядке. Для этого вам понадобится фиксированный битрейт, и может быть довольно сложно найти, где в файле нужно перейти к следующему.
Я быстро взглянул на сайт irrKlang, и они могут похвастаться возможностью написать свои собственные устройства чтения / декодирования форматов файлов для расширения движка с ним, так что вы можете попробовать это.
Существует также учебник здесь , чтобы отменить доступ к файлам - вы могли бы дать свою оригинальную идею выстрел, или вы можете смешать его с несколькими звуками , как сказал Elideb. Вы можете расширить свой класс CMyReadFile, чтобы иметь доступ к нескольким файлам (таким как PartA.wav, PartB.wav, PartC.wav), и вы можете переопределить метод read, вместо того, чтобы просто:
Вы могли бы сделать что-то вроде:
Это означает, что песня будет легко менять раздел без синхронизации Plays & Stops.
источник