ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/MacOSX/audio_macosx.cpp
Revision: 1.6
Committed: 2008-01-01T09:40:32Z (16 years, 4 months ago) by gbeauche
Branch: MAIN
CVS Tags: HEAD
Changes since 1.5: +1 -1 lines
Log Message:
Happy New Year!

File Contents

# Content
1 /*
2 * audio_macosx.cpp - Audio support, implementation Mac OS X
3 * Copyright (C) 2006, Daniel Sumorok
4 *
5 * Basilisk II (C) 1997-2008 Christian Bauer
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22 #include "sysdeps.h"
23
24 #include <sys/ioctl.h>
25 #include <unistd.h>
26 #include <errno.h>
27 #include <pthread.h>
28 #include <semaphore.h>
29
30 #include "cpu_emulation.h"
31 #include "main.h"
32 #include "prefs.h"
33 #include "user_strings.h"
34 #include "audio.h"
35 #include "audio_defs.h"
36 #include "MacOSX_sound_if.h"
37
38 #define DEBUG 0
39 #include "debug.h"
40
41
42 // The currently selected audio parameters (indices in
43 // audio_sample_rates[] etc. vectors)
44 static int audio_sample_rate_index = 0;
45 static int audio_sample_size_index = 0;
46 static int audio_channel_count_index = 0;
47
48 // Prototypes
49 static OSXsoundOutput *soundOutput = NULL;
50 static bool main_mute = false;
51 static bool speaker_mute = false;
52
53 /*
54 * Initialization
55 */
56 static int audioInt(void);
57
58 static bool open_audio(void)
59 {
60 AudioStatus.sample_rate = audio_sample_rates[audio_sample_rate_index];
61 AudioStatus.sample_size = audio_sample_sizes[audio_sample_size_index];
62 AudioStatus.channels = audio_channel_counts[audio_channel_count_index];
63
64 if (soundOutput)
65 delete soundOutput;
66
67 soundOutput = new OSXsoundOutput();
68 soundOutput->start(AudioStatus.sample_size, AudioStatus.channels,
69 AudioStatus.sample_rate >> 16);
70 soundOutput->setCallback(audioInt);
71 audio_frames_per_block = soundOutput->bufferSizeFrames();
72
73 audio_open = true;
74 return true;
75 }
76
77 void AudioInit(void)
78 {
79 // Sound disabled in prefs? Then do nothing
80 if (PrefsFindBool("nosound"))
81 return;
82
83 //audio_sample_sizes.push_back(8);
84 audio_sample_sizes.push_back(16);
85
86 audio_channel_counts.push_back(1);
87 audio_channel_counts.push_back(2);
88
89 audio_sample_rates.push_back(11025 << 16);
90 audio_sample_rates.push_back(22050 << 16);
91 audio_sample_rates.push_back(44100 << 16);
92
93 // Default to highest supported values
94 audio_sample_rate_index = audio_sample_rates.size() - 1;
95 audio_sample_size_index = audio_sample_sizes.size() - 1;
96 audio_channel_count_index = audio_channel_counts.size() - 1;
97
98 AudioStatus.mixer = 0;
99 AudioStatus.num_sources = 0;
100 audio_component_flags = cmpWantsRegisterMessage | kStereoOut | k16BitOut;
101 audio_component_flags = 0;
102
103 open_audio();
104 }
105
106
107 /*
108 * Deinitialization
109 */
110
111 static void close_audio(void)
112 {
113 D(bug("Closing Audio\n"));
114
115 if (soundOutput)
116 {
117 delete soundOutput;
118 soundOutput = NULL;
119 }
120
121 audio_open = false;
122 }
123
124 void AudioExit(void)
125 {
126 // Close audio device
127 close_audio();
128 }
129
130
131 /*
132 * First source added, start audio stream
133 */
134
135 void audio_enter_stream()
136 {
137 // Streaming thread is always running to avoid clicking noises
138 }
139
140
141 /*
142 * Last source removed, stop audio stream
143 */
144
145 void audio_exit_stream()
146 {
147 // Streaming thread is always running to avoid clicking noises
148 }
149
150
151 /*
152 * MacOS audio interrupt, read next data block
153 */
154
155 void AudioInterrupt(void)
156 {
157 D(bug("AudioInterrupt\n"));
158 uint32 apple_stream_info;
159 uint32 numSamples;
160 int16 *p;
161 M68kRegisters r;
162
163 if (!AudioStatus.mixer)
164 {
165 numSamples = 0;
166 soundOutput->sendAudioBuffer((void *)p, (int)numSamples);
167 D(bug("AudioInterrupt done\n"));
168 return;
169 }
170
171 // Get data from apple mixer
172 r.a[0] = audio_data + adatStreamInfo;
173 r.a[1] = AudioStatus.mixer;
174 Execute68k(audio_data + adatGetSourceData, &r);
175 D(bug(" GetSourceData() returns %08lx\n", r.d[0]));
176
177 apple_stream_info = ReadMacInt32(audio_data + adatStreamInfo);
178 if (apple_stream_info && (main_mute == false) && (speaker_mute == false))
179 {
180 numSamples = ReadMacInt32(apple_stream_info + scd_sampleCount);
181 p = (int16 *)Mac2HostAddr(ReadMacInt32(apple_stream_info + scd_buffer));
182 }
183 else
184 {
185 numSamples = 0;
186 p = NULL;
187 }
188
189 soundOutput->sendAudioBuffer((void *)p, (int)numSamples);
190
191 D(bug("AudioInterrupt done\n"));
192 }
193
194
195 /*
196 * Set sampling parameters
197 * "index" is an index into the audio_sample_rates[] etc. vectors
198 * It is guaranteed that AudioStatus.num_sources == 0
199 */
200
201 bool audio_set_sample_rate(int index)
202 {
203 close_audio();
204 audio_sample_rate_index = index;
205 return open_audio();
206 }
207
208 bool audio_set_sample_size(int index)
209 {
210 close_audio();
211 audio_sample_size_index = index;
212 return open_audio();
213 }
214
215 bool audio_set_channels(int index)
216 {
217 close_audio();
218 audio_channel_count_index = index;
219 return open_audio();
220 }
221
222 /*
223 * Get/set volume controls (volume values received/returned have the
224 * left channel volume in the upper 16 bits and the right channel
225 * volume in the lower 16 bits; both volumes are 8.8 fixed point
226 * values with 0x0100 meaning "maximum volume"))
227 */
228 bool audio_get_main_mute(void)
229 {
230 return main_mute;
231 }
232
233 uint32 audio_get_main_volume(void)
234 {
235 return 0x01000100;
236 }
237
238 bool audio_get_speaker_mute(void)
239 {
240 return speaker_mute;
241 }
242
243 uint32 audio_get_speaker_volume(void)
244 {
245 return 0x01000100;
246 }
247
248 void audio_set_main_mute(bool mute)
249 {
250 main_mute = mute;
251 }
252
253 void audio_set_main_volume(uint32 vol)
254 {
255 }
256
257 void audio_set_speaker_mute(bool mute)
258 {
259 speaker_mute = mute;
260 }
261
262 void audio_set_speaker_volume(uint32 vol)
263 {
264 }
265
266 static int audioInt(void)
267 {
268 SetInterruptFlag(INTFLAG_AUDIO);
269 TriggerInterrupt();
270 return 0;
271 }