Когда экран заблокирован, график Обработки Аудиоустройства - Гарантирующий воспроизведение аудио продолжается
Q: Я использую AUGraph, и я хотел бы, чтобы мое аудио продолжало играть во время экранной блокировки. Есть ли что-либо еще, что я должен сконфигурировать в дополнение к Аудио Сеансу kAudioSessionCategory_MediaPlayback категорию, чтобы позволить моему AURenderCallback продолжать вызываться?
A: Я использую AUGraph, и я хотел бы, чтобы мое аудио продолжало играть во время экранной блокировки. Есть ли что-либо еще, что я должен сконфигурировать в дополнение к Аудио Сеансу kAudioSessionCategory_MediaPlayback категорию, чтобы позволить моему AURenderCallback продолжать вызываться?
Когда График Обработки Аудиоустройства используется для Вывода только, размер рендеринга I/O по умолчанию изменяется от 22 миллисекунд (1 024 выборки 44.1 кГц) к 88 миллисекундам (4 096 выборок 44.1 кГц), когда заблокирован экран. Это сделано для сохранения питания, так как нет никакого взаимодействия с пользователем с экраном, как только экран идет темный.
Если приложение не составляет это изменение, любое Аудиоустройство попросило обеспечивать, 4 096 выборок возвратят ошибку начиная с kAudioUnitProperty_MaximumFramesPerSlice установка будет меньше, чем это значение.
Удаленное Аудиоустройство I/O по умолчанию уже сконфигурировано для 4 096 максимальных кадров на часть, проблема влияет на все другие Аудиоустройства, используемые в графике.
Если приложение намеревается продолжать воспроизведение, когда экран заблокирован, это - клиентская ответственность измениться kAudioUnitProperty_MaximumFramesPerSlice свойство соответственно для каждого Аудиоустройства, используемого для обрабатывания запросов для 4 096 выборок.
Перечисление 1 Типичная установка Графика Аудиоустройства, конфигурирующая kAudioUnitProperty_MaximumFramesPerSlice свойство для микшера.
// audio render procedure
static OSStatus renderProc(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber,
UInt32 inNumberFrames, AudioBufferList *ioData)
{
// your audio render code here
return noErr;
}
AUGraph mGraph;
AudioUnit mMixer;
- (void)initializeAUGraph
{
// create two AudioComponentDescriptions for the AUs we want in the graph
// output unit
AudioComponentDescription output_desc = {kAudioUnitType_Output, kAudioUnitSubType_RemoteIO,
kAudioUnitManufacturer_Apple, 0, 0};
// multichannel mixer unit
AudioComponentDescription mixer_desc = {kAudioUnitType_Mixer, kAudioUnitSubType_MultiChannelMixer,
kAudioUnitManufacturer_Apple, 0, 0};
AUNode outputNode;
AUNode mixerNode;
CAStreamBasicDescription desc;
// create a new AUGraph
NewAUGraph(&mGraph);
// create a node in the graph that is an AudioUnit, using the supplied AudioComponentDescription
// to find and open that unit
AUGraphAddNode(mGraph, &output_desc, &outputNode);
AUGraphAddNode(mGraph, &mixer_desc, &mixerNode);
// connect a node's output to a node's input
AUGraphConnectNodeInput(mGraph, mixerNode, 0, outputNode, 0);
// open the graph AudioUnits are open but not initialized (no resource allocation occurs here)
AUGraphOpen(mGraph);
// get the mixer audio unit since we need to configure it
AUGraphNodeInfo(mGraph, mixerNode, NULL, &mMixer);
// set bus count
UInt32 numbuses = 1;
AudioUnitSetProperty(mMixer, kAudioUnitProperty_ElementCount, kAudioUnitScope_Input, 0, &numbuses,
sizeof(numbuses));
// setup render callback struct
AURenderCallbackStruct rcbs;
rcbs.inputProc = &renderProc;
rcbs.inputProcRefCon = self;
// Set a callback for the specified node's specified input
AUGraphSetNodeInputCallback(mGraph, mixerNode, 0, &rcbs);
// set input stream format to what we want
UInt32 size = sizeof(desc);
AudioUnitGetProperty(mMixer, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &desc, &size);
desc.ChangeNumberChannels(2, false);
desc.mSampleRate = 44100.0;
AudioUnitSetProperty(mMixer, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &desc,
sizeof(desc));
// set output stream format to what we want
AudioUnitGetProperty(mMixer, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &desc, &size);
desc.ChangeNumberChannels(2, false);
desc.mSampleRate = 44100.0;
AudioUnitSetProperty(mMixer, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &desc,
sizeof(desc));
// set the mixer unit to handle 4096 samples per slice since we want to keep rendering during screen lock
UInt32 maxFPS = 4096;
AudioUnitSetProperty(mMixer, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 0,
&maxFPS, sizeof(maxFPS));
// now that we've set everything up we can initialize the graph, this will also validate the connections
AUGraphInitialize(mGraph);
} |
История версии документа
| Дата | Примечания |
|---|---|
| 15.03.2010 | Передовая статья. |
| 14.01.2010 | Исправленное значение для максимума AU по умолчанию структурирует на часть. |
| 14.12.2009 | Передовая статья |
| 09.12.2009 | Новый документ, обсуждающий, как гарантировать воспроизведение аудио, в то время как телефон заблокирован при использовании многократных Аудиоустройств. |