Главная » Программирование звука » Двойная буферизация воспроизведения звука

0

Выбор устройства воспроизведения звука в операционной системе Mac OS несложен.  Сообщите  системе тип  производимого  вашей  программой  звука  (в  нашем случае  sampledSynth),  а  система  подберет  вам  подходящее  устройство.  Для  использования   двойной   буферизации   понадобится   структура   SndDoubleBufferHeader,  в  которой  содержатся  указатели  на  две  структуры  SndDoubleBuffer. Последние и являются непосредственно буферами, требующими инициализации.

Отметим два интересных отличия от других систем. Первое заключается в описании  частоты  дискретизации  как  переменной  типа  Fixed,  что  позволяет  использовать  дробные  частоты  дискретизации.  Вторым  отличием  является  то,  что  функции обратного вызова требуют особого обращения. Так как операционная система Mac  OS  для  PowerPC  представляет  собой  смесь  собственных  программ  для  PowerPC  и  программ  для  эмулируемого  процессора  680×0,  указатели  на  функции  обратного вызова должны быть описаны как универсальные указатели на процедуры (universal  procedure  pointers),  использование  которых  позволит  обоим  типам  системных  программ  корректно  обращаться  к  функциям,  определенным  в  вашей собственной программе. Te же самые вызовы применяются и в Mac OS для процессора 680×0, хотя на низком уровне их реализация проще.

Листинг 7.3. Реализация класса Масрlауеr (продолжение)

void MacPlayer::Play(void (*serviceFunc)(void)) { SCStatus         Stats;

SndChannelPtr      chan;

chan = nil;

OSErr err = SndNewChannel (&chan, sampledSynth, 0, nil);

if (err != noErr) Debugger();

SndDoubleBufferHeader doubleHeader; doubleHeader.dbhNumChannels = Channels(); doubleHeader.dbhSampleSize = 16;     // Количество битов

// на   отсчет.

doubleHeader.dbhCompressionID = 0;   // Звук не   сжат.

doubleHeader.dbhPacketSize = 0;      // He используется,

doubleHeader.dbhSampleRate =

// так как нет компрессии.

static_cast<Fixed>(SamplingRate()) << 16;

/* Создаем  UPP для SndDoubleBackProc. */

doubleHeader.dbhDoubleBack = NewSndDoubleBackProc(NextBlockCallback);

// Инициализация  очереди после

// проведенных  согласований.

InitializeQueue(128 * 1024L);  // Выделяем  128 Кб  под   очередь.

for (int i = 0; i <= 1; ++i) { SndDoubleBufferPtr doubleBuffer =

reinterpret_cast<SndDoubleBufferPtr> (NewPtrClear(sizeof(SndDoubleBuffer) +

doubleBufferSize*2));

doubleHeader.dbhBufferPtr [i] = doubleBuffer;

if ((doubleBuffer == nil) || (MemError() != 0)) Debugger();

doubleBuffer->dbNumFrames = 0;

doubleBuffer->dbFlags = 0;

doubleBuffer->dbUserInfo [0] = static_cast<long>(this); NextBlockCallback(chan, doubleBuffer); // Инициализация

// буферов.

}

err = SndPlayDoubleBuffer (chan, &doubleHeader);

if (err != noErr) Debugger();

do {

FillQueue();           // Поддерживаем наполнение  очереди.

if (serviceFunc)

serviceFunc();      // Вызываем  функции  сервиса.

err = SndChannelStatus (chan, sizeof (Stats), &Stats);

} while (Stats.scChannelBusy);

DisposePtr ((Ptr) doubleHeader.dbhBufferPtr[0]); DisposePtr ((Ptr) doubleHeader.dbhBufferPtr[1]); err = SndDisposeChannel (chan,0);

if (err != noErr)

Debugger();

}

Источник: Кинтцель Т.  Руководство программиста по работе со звуком = A Programmer’s Guide to Sound: Пер. с англ. М.: ДМК Пресс, 2000. 432 с, ил. (Серия «Для программистов»).

По теме:

  • Комментарии