1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 // Disable symbol overrides so that we can use system headers.
24 #define FORBIDDEN_SYMBOL_ALLOW_ALL
25 
26 #include "backends/platform/iphone/osys_main.h"
27 
AQBufferCallback(void * in,AudioQueueRef inQ,AudioQueueBufferRef outQB)28 void OSystem_IPHONE::AQBufferCallback(void *in, AudioQueueRef inQ, AudioQueueBufferRef outQB) {
29 	//printf("AQBufferCallback()\n");
30 	if (s_AudioQueue.frameCount > 0 && s_soundCallback != NULL) {
31 		outQB->mAudioDataByteSize = 4 * s_AudioQueue.frameCount;
32 		s_soundCallback(s_soundParam, (byte *)outQB->mAudioData, outQB->mAudioDataByteSize);
33 		AudioQueueEnqueueBuffer(inQ, outQB, 0, NULL);
34 	} else {
35 		AudioQueueStop(s_AudioQueue.queue, false);
36 	}
37 }
38 
mixCallback(void * sys,byte * samples,int len)39 void OSystem_IPHONE::mixCallback(void *sys, byte *samples, int len) {
40 	OSystem_IPHONE *this_ = (OSystem_IPHONE *)sys;
41 	assert(this_);
42 
43 	if (this_->_mixer) {
44 		this_->_mixer->mixCallback(samples, len);
45 	}
46 }
47 
setupMixer()48 void OSystem_IPHONE::setupMixer() {
49 	_mixer = new Audio::MixerImpl(AUDIO_SAMPLE_RATE);
50 
51 	s_soundCallback = mixCallback;
52 	s_soundParam = this;
53 
54 	startSoundsystem();
55 }
56 
startSoundsystem()57 void OSystem_IPHONE::startSoundsystem() {
58 	s_AudioQueue.dataFormat.mSampleRate = AUDIO_SAMPLE_RATE;
59 	s_AudioQueue.dataFormat.mFormatID = kAudioFormatLinearPCM;
60 	s_AudioQueue.dataFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
61 	s_AudioQueue.dataFormat.mBytesPerPacket = 4;
62 	s_AudioQueue.dataFormat.mFramesPerPacket = 1;
63 	s_AudioQueue.dataFormat.mBytesPerFrame = 4;
64 	s_AudioQueue.dataFormat.mChannelsPerFrame = 2;
65 	s_AudioQueue.dataFormat.mBitsPerChannel = 16;
66 	s_AudioQueue.frameCount = WAVE_BUFFER_SIZE;
67 
68 	if (AudioQueueNewOutput(&s_AudioQueue.dataFormat, AQBufferCallback, &s_AudioQueue, 0, kCFRunLoopCommonModes, 0, &s_AudioQueue.queue)) {
69 		printf("Couldn't set the AudioQueue callback!\n");
70 		_mixer->setReady(false);
71 		return;
72 	}
73 
74 	uint32 bufferBytes = s_AudioQueue.frameCount * s_AudioQueue.dataFormat.mBytesPerFrame;
75 
76 	for (int i = 0; i < AUDIO_BUFFERS; i++) {
77 		if (AudioQueueAllocateBuffer(s_AudioQueue.queue, bufferBytes, &s_AudioQueue.buffers[i])) {
78 			printf("Error allocating AudioQueue buffer!\n");
79 			_mixer->setReady(false);
80 			return;
81 		}
82 
83 		AQBufferCallback(&s_AudioQueue, s_AudioQueue.queue, s_AudioQueue.buffers[i]);
84 	}
85 
86 	AudioQueueSetParameter(s_AudioQueue.queue, kAudioQueueParam_Volume, 1.0);
87 	if (AudioQueueStart(s_AudioQueue.queue, NULL)) {
88 		printf("Error starting the AudioQueue!\n");
89 		_mixer->setReady(false);
90 		return;
91 	}
92 
93 	_mixer->setReady(true);
94 }
95 
stopSoundsystem()96 void OSystem_IPHONE::stopSoundsystem() {
97 	AudioQueueStop(s_AudioQueue.queue, true);
98 
99 	for (int i = 0; i < AUDIO_BUFFERS; i++) {
100 		AudioQueueFreeBuffer(s_AudioQueue.queue, s_AudioQueue.buffers[i]);
101 	}
102 
103 	AudioQueueDispose(s_AudioQueue.queue, true);
104 	_mixer->setReady(false);
105 }
106