SDL logo

Проблему решил, но дабы пояснить суть вопроса начну сначала.

В одном из проектов используется SDL_mixer для проигрывания музыки (ogg) и звуковых эффектов (тот же ogg, wav).
В целом качество звука устраивает, но на некоторых музыкальных треках при наступлении loop слышится треск и хрип. Это не допустимо. Ладно, попробовал использовать OpenAL – все чудно, никаких нареканий нет. Но работа с OpenAL у меня ещё не отлажена, посему переводить уже готовый проект на него очень боязно.

Проблемы с SDL_mixer происходят и под Linux, и под Windows, и под Mac OS X (хотя тут особо не тестировалось).

Может есть какие то методы или обходные пути для решения моей проблемы?

Инициализация и работа выполняется так (лишнее поскипано):

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// ---------------------------------------------------
// инициализация подсистемы (видео уже инициализировано)
SDL_InitSubSystem(SDL_INIT_AUDIO);
int sample_rate = 44100;
// изначально использовался AUDIO_S16, разницы незаметно
Uint16 audio_format = AUDIO_S16SYS;
int audio_channels = 2;
// размер буфера менялся в широких пределах,
// но он влияет только на задержку перед проигрыванием эффекта
if (Mix_OpenAudio(sample_rate, audio_format, audio_channels, 4096))
{
// ошибка, уходим
}
Mix_QuerySpec(&sample_rate, &audio_format, &audio_channels);
// тут получаем, а затем пишем в лог реально установленные значения
// (значения запрошенные не отличаются от реально установленных)
// ---------------------------------------------------
// загружаем музыкальный трек
// тут передается путь к музыкальному треку на диске
handle = Mix_LoadMUS(filename);
// ---------------------------------------------------
// говорим играть музыкальный трек,
// его громкость плавно нарастает за время fadeinms.
Mix_FadeInMusic(handle, -1, fadeinms);
// --------------------------------------------------- // инициализация подсистемы (видео уже инициализировано) SDL_InitSubSystem(SDL_INIT_AUDIO); int sample_rate = 44100; // изначально использовался AUDIO_S16, разницы незаметно Uint16 audio_format = AUDIO_S16SYS; int audio_channels = 2; // размер буфера менялся в широких пределах, // но он влияет только на задержку перед проигрыванием эффекта if (Mix_OpenAudio(sample_rate, audio_format, audio_channels, 4096)) { // ошибка, уходим } Mix_QuerySpec(&sample_rate, &audio_format, &audio_channels); // тут получаем, а затем пишем в лог реально установленные значения // (значения запрошенные не отличаются от реально установленных) // --------------------------------------------------- // загружаем музыкальный трек // тут передается путь к музыкальному треку на диске handle = Mix_LoadMUS(filename); // --------------------------------------------------- // говорим играть музыкальный трек, // его громкость плавно нарастает за время fadeinms. Mix_FadeInMusic(handle, -1, fadeinms);
// ---------------------------------------------------
// инициализация подсистемы (видео уже инициализировано)
SDL_InitSubSystem(SDL_INIT_AUDIO);

int sample_rate = 44100;
// изначально использовался AUDIO_S16, разницы незаметно
Uint16 audio_format = AUDIO_S16SYS;
int audio_channels = 2;

// размер буфера менялся в широких пределах,
// но он влияет только на задержку перед проигрыванием эффекта
if (Mix_OpenAudio(sample_rate, audio_format, audio_channels, 4096))
{
   // ошибка, уходим
}

Mix_QuerySpec(&sample_rate, &audio_format, &audio_channels);
// тут получаем, а затем пишем в лог реально установленные значения
// (значения запрошенные не отличаются от реально установленных)

// ---------------------------------------------------
// загружаем музыкальный трек
// тут передается путь к музыкальному треку на диске
handle = Mix_LoadMUS(filename);

// ---------------------------------------------------
// говорим играть музыкальный трек,
// его громкость плавно нарастает за время fadeinms.
Mix_FadeInMusic(handle, -1, fadeinms);

Моё решение проблемы:

Запускаю трек играться только ОДИН раз – Mix_FadeInMusic(handle, 0, fadeinms). Если был запрос на бесконечное проигрывание трека, то запоминаю его хэндл.
В главном цикле движка проверяю, есть ли хэндл на музыкальный трек, который должен проигрываться бесконечно. Если хэндл есть, а проигрывание трека прекратилось, то я просто запускаю проигрывание трека заново.

Вот такой вот костыль пришлось использовать. Работоспособность данного костыля была проверена на Linux и Windows. Mac OS X пока не проверял.

Изначально данный вопрос поднимал на GameDev.ru.