Главная » Программирование звука » Пример программы для Mac OS

0

Разрабатывая  программу  для  Windows,  я  использовал  текстовый  режим  для того,  чтобы  не  усложнять  программу.  B  Mac  OS  аналогичных  возможностей  не предусмотрено, поэтому мне предстоит более сложная работа.

Листинг 7.4. Программа macmain.cpp

#include "audio.h"

#include "open.h"

#include "aplayer.h"

#include "macplayr.h"

#include <fstream>

static void InitializeSystem();

static void CheckEvent();

static void DoClick(EventRecord *event);

static void PlayFileSpec(FSSpec *fileSpec);

int main() { InitializeSystem();

cout << "Select File : Play.. to play a file.\n";

while(1) CheckEvent();

return 0;

}

Функция  InitializeSystem инициализирует  Macintosh  Toolbox  и  ряд  дополнительных  утилит.  CheckEvent ожидает  наступления  определенного  события  и  обрабатывает  его.  DoClick обрабатывает  событие,  возникающее  при  щелчке  кнопкой мыши.  И  наконец,  функция  PlayFileSpec получает  используемую  на  компьютерах Macintosh спецификацию файла и непосредственно открывает и воспроизводит файл. Заметим, что метод МасР1ауеr::Play() (файл  mаср1ау.срр) также должен  регулярно  проверять  наступление  событий,  поэтому  ему  также  будет  передан  указатель  на CheckEvent.

Функция    поддержки    консоли    SIOUX    (стандартное    расширение    ввода/вы-

вода  для   пользователя),  обеспечиваемая   средой  разработки   Metrowerks   CodeWarrior,  управляя  текстовым  окном,  поддерживает  ввод/вывод  в  стандартные  для  C++ ветви cin, cout и cerr. Тем не менее, так как я подготовил мои собственные варианты  для  цикла  событий  и  меню,  мне  необходимо  отключить  часть  настроек, используемых в SIOUX по умолчанию.

Листинг 7.5. Системная поддержка в Macintosh

#include <SIOUX.h>

static void InitializeSystem() {  // Инициализация  системных

// компонентов.

InitGraf(&qd.thePort);          // QuickDraw. InitFonts();                     // Менеджер  шрифтов. FlushEvents(everyEvent,0);      // Отбрасываем   все   ожидающие

// события. InitWindows();                   // Менеджер  окон. InitMenus();                    // Менеджер  меню. TEInit();                       // Расширения для  работы

// с текстом.

InitDialogs(nil);         // Менеджер  диалога. InitCursor();             // Курсор.

// Изменяем исходные значения  SIOUX. SIOUXSettings.standalone = FALSE;

SIOUXSettings.setupmenus = FALSE; SIOUXSettings.initializeTB = FALSE; SIOUXSettings.autocloseonquit = TRUE; SIOUXSettings.columns = 80; SIOUXSettings.rows = 12; SIOUXSettings.asktosaveonclose = 0; SIOUXSetTitle("\pPlay Sound");

// Настройка  меню.

Handle menuBar = GetNewMBar(128);    // Берем  строку   меню

// из ресурсов.

SetMenuBar(menuBar); DisposeHandle(menuBar);

MenuHandle appleMenu = GetMenuHandle(128); // Получаем

// меню  Apple.

AppendResMenu(appleMenu,’DRVR’);     // Добавляем системные

// входы в  меню  Apple.

DrawMenuBar();                       // Обновляем  строку меню.

}

Сначала  функция  CheckEvent предлагает  обработать  новое  событие  библиотеке SIOUX. Если эта библиотека не может произвести обработку, то ее выполняет непосредственно CheckEvent. Так как я явно работаю только с меню, мне необходимо позаботиться лишь о событиях mouseDown.

Листинг 7.5. Системная поддержка в Macintosh (продолжение)

static void CheckEvent() { EventRecord event; Boolean  eventOccured;

eventOccured = WaitNextEvent(everyEvent, &event, 10, nil);

if(eventOccured && !SIOUXHandleOneEvent(&event)) {

switch(event.what) {

case mouseDown: DoClick(&event); break;

default:                           break;

}

}

}

B  нашей  тестовой  программе  используется  только  одно  меню  (FiIe),  в  котором находятся всего две строки: Play… (воспроизведение…) и Quit (выход). При выборе строки Play… вызывается стандартная диалоговая панель выбора файла, после  чего  указанный  вами  файл  воспроизводится.  Выбор  строки  Quit приводит  к  выходу  из  программы.  Щелчок  мышью  по  Apple  Menu  обрабатывается  путем обращения к системному вызову OpenDeskAcc.

Листинг 7.5. Системная поддержка в Macintosh (продолжение)

static void DoClick(EventRecord *event) { WindowPtr whichWindow;

switch(FindWindow(event->where,&whichWindow)) {

case inMenuBar:

long select = MenuSelect(event->where);

switch(select >> 16) {

case 128:                    // Меню  Apple.

{

MenuHandle mh = GetMenuHandle(select >> 16);

unsigned char itemName[255];

GetMenuItemText(mh, (select & 0xFFFF), itemName); OpenDeskAcc(itemName);

HiliteMenu(0);

break;

}

case 129:                    // Меню  File. switch(select & 0xFFFF) {

case 1:                  // Выбрано  File : Play…

// Вызов   стандартной  диалоговой

// панели  выбора файла.

SFTypeList typeList; StandardFileReply selectedFile; StandardGetFile (

// Нет   фильтрации.

reinterpret_cast<RoutineDescriptor *>(nil),

-1,                // Все   типы.

typeList,          // He используется.

&selectedFile);    // Возвращаем  информацию

// о  выбранном  файле.

// Блокируем пункт  Play…

MenuHandle mh = GetMenuHandle(129); DisableItem(mh,1);

HiliteMenu(0); DrawMenuBar();

// Воспроизводим  файл.

PlayFileSpec(&selectedFile.sfFile);

// Деблокируем пункт  Play…

EnableItem(mh,1); DrawMenuBar(); break;

case 2: // Выход

exit(0);

}

}

break;

}

}

Воспроизведение файла в Mac OS

После того  как файл выбран, нам необходимо его воспроизвести. При этом нужно учитывать ряд особенностей Mac Toolbox. Первая из них заключается в том,

что  структура  FSSpec представляет  собой  строку  в  формате  языка  Паскаль,  которая  должна  быть  преобразована  в  соответствии  с  форматами,  используемыми в С/С++. Вторая особенность в том, что структура FSSpec может указывать на файл, расположенный в любой доступной системе директории. Прежде чем открывать  этот файл,  необходимо  установить  в  качестве  текущей  рабочей  директории и текущего диска те директорию и диск, где расположен файл.

Листинг 7.5. Системная поддержка в Macintosh (продолжение)

static void PlayFileSpec(FSSpec *fileSpec) {

char *name = reinterpret_cast<char *>(p2cstr(fileSpec->name));

// Файл  " имя  "

cerr << "File: " << name << "\n";

short volumeId;

OpenWD(fileSpec->vRefNum,fileSpec->parID,NULL, &volumeId); SetVol(NULL,volumeId);

ifstream input(name, ios_base::in | ios_base::binary);

if (!input.is_open()) {

// He удалось  открыть

// << имя   файла  <<

cerr << "Couldn’t open file " << name << "\n";

return;

}

AudioAbstract *audioRead = OpenFormat(input);

if (audioRead) {

MacPlayer player(audioRead); player.Play(CheckEvent); delete audioRead;

// Окончено воспроизведение

// << имя   файла  <<.

cerr << "Finished playing " << name << ".\n";

}

cerr << "\n";

}

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

По теме:

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