Главная » iPhone » Пример: магнитофон iPhone

0

Данный пример может запускаться из командной строки с именем файла и длительностью как на iPhone, так и на настольной системе. Он записывает данные с микрофона в течение заданного периода времени и сохраняет их в файл с указанным именем. Поскольку Leonard также содержит платформу Audio Toolbox, то данный пример может быть скомпилирован как для iPhone, так и для настольной системы:

$ arm-apple-darwin9-gcc -о recorder recorder.c ^ -framework AudioToolbox -framework CoreAudio -framework CoreFoundation Ъ

-DMAC_OS_X_VERSION_MAX_ALLOWED=MAC_OS_X_VERSION_10_5 -DMAC_OS_X_VERSION MIN REQUIRED=MAC OS X VERSION 10 5

$ gcc -о recorder recorder.с

-framework AudioToolbox -framework CoreAudio -framework CoreFoundation

В листинге 6.4 приведен соответствующий код.

# include <AudioToolbox/AudioQueue.h> #include <AudioToolbox/AudioFile.h> #include <AudioToolbox/AudioConverter.h>

#include <stdio.h> #include <stdlib.h> #include <errno.h> #include <sys/stat.h> ?include <sys/select.h> #define AUDIO_BUFFERS 3

typedef struct AQCallbackStruct {

AudioStreamBasicDescription mDataFormat; AudioQueueRef queue;

AudioQueueBufferRef mBuffers[AUDIO_BUFFERS] ; AudioFilelD outputFile; unsigned long frameSize; long long recPtr; int run; } AQCallbackStruct;

static void AQInputCallback ( void *aqr, AudioQueueRef inQ, AudioQueueBufferRef inQB, const AudioTimeStamp *timestamp, unsigned long ‘frameSize,

const AudioStreamPacketDescription *mDataFormat)

(

AQCallbackStruct *aqc = (AQCallbackStruct *) aqr; /* Записьшаем данные в файл */

if (AudioFileWritePackets (aqc->outputFile, false, inQB->mAudioDataByteSize,

mDataFormat, aqc->recPtr, SframeSize, inQB->mAudioData) ~ noErr)

{

aqc->recPtr += frameSize;

/* Если мы собираемся остановить запись, то не ставим звуковые буферы в очередь. */ if (!aqc->run) return;

AudioQueueEnqueueBuffer (aqc->queue, inQB, 0, NULL);

}

int main(int argc, char *argv[]) { AQCallbackStruct aqc; AudioFileTypelD fileFormat; CFURLRef filename; struct timeval tv; int i;

if (argc < 3) {

fprintf(stderr, "Syntax: %s [filename] [duration]", argv[0]); exit(EXIT_FAILURE);

}

aqc.mDataFormat.mFormatID = kAudioFormatLinearPCM;

aqc.mDataFormat.mSampleRate = 44100.0;

aqc.mDataFormat.mChannelsPerFrame = 2;

aqc.mDataFormat.mBitsPerChannel = 16;

aqc.mDataFormat.mBytesPerPacket =

aqc.mDataFormat.mBytesPerFrame =

aqc.mDataFormat.mChannelsPerFrame * sizeof (short int); aqc.mDataFormat.mFramesPerPacket = 1;

aqc.mDataFormat.mFormatFlags = kLinearPCMFormatFlaglsBigEndian

I kLinearPCMFormatFlaglsSignedlnteger I kLinearPCMFormatFlaglsPacked;

aqc.frameSize = 735;

AudioQueueNewInput (Saqc.mDataFormat, AQInputCallback, Saqc, NULL, kCFRunLoopCommonModes, 0, &aqc.queue);

/* Создаем выходной файл */ fileFormat = kAudioFileAIFFType;

filename = CFURLCreateFromFileSystemRepresentation (NULL, argv[l], strlen (argv[l]), false);

AudioFileCreateWithURL(filename, fileFormat,

&aqc.mDataFormat, kAudioFileFlags EraseFile, &aqc.outputFile) ;

/* Инициализируем буферы записи */ for (1=0; i<AUDI0_BUFFERS; i++) { AudioQueueAllocateBuffer (aqc.queue, aqc.frameSize,

&aqc.mBuffers[i]) ; AudioQueueEnqueueBuffer (aqc.queue, aqc.mBuffers[i], 0, NULL);

}

aqc.recPtr = 0; aqc.run = 1;

AudioQueueStart (aqc.queue, NULL);

/* Ждем некоторое время, пока идет запись */ tv.tv_sec = atof(argv[2]); tv.tv_usec = 0;

select(0, NULL, NULL, NULL, &tv);

/* Завершаем запись */ AudioQueueStop (aqc.queue, true); aqc.run = 0;

AudioQueueDispose (aqc.queue, true); AudioFileClose (aqc.outputFile);

exit(EXITSUCCESS);

Как это работает

Программа record работает следующим образом:

1.    В начале программы вызывается функция приложения maino, которая извлекает имя файла из списка аргументов (передаваемого в командной строке).

2.    Функция main() создает нашу задаваемую пользователем структуру, чья конструкция декларируется в начале программы. Эта структура хранит указатели на аудиоочередь, звуковые буферы и созданный выходной файл. Кроме того, она содержит длину дорожки и целое число recPtr, которое выступает в роли записывающей иглы, определяя последнюю дорожку, записанную на диск.

3.     Инициализируется и запускается новая звуковая очередь. Инициализируется и ставится в эту очередь записи каждый звуковой буфер. Затем стартует аудиоочередь. После этого программа ждет, когда закончится запись текущей дорожки.

4.     По мере записи аудио звуковые буферы отправляются к функции обратного вызова, где они, один за другим, опустошаются. Каждый раз, когда ка- кой-либо буфер опустошается, вызывается функция AQinputCallback.

5.    Функция AQinputCallback увеличивает значение записывающей иглы и копирует звуковой фрейм на диск.

Источник: Здзиарски Дж. iPhone. Разработка приложений с открытым кодом: Пер„с англ. — 2-е изд., перераб. и доп. — СПб.: БХВ-Петербург, 2009. — 368 е.: ил.

По теме:

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