ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/MacOSX/audio_macosx.cpp
Revision: 1.5
Committed: 2006-08-01T03:31:46Z (18 years, 3 months ago) by nigel
Branch: MAIN
Changes since 1.4: +1 -1 lines
Log Message:
Do'h. Checked in and shipped a DEBUG=1. Thanks to Steve Green for his fast eyes.

File Contents

# User Rev Content
1 nigel 1.1 /*
2 nigel 1.4 * audio_macosx.cpp - Audio support, implementation Mac OS X
3     * Copyright (C) 2006, Daniel Sumorok
4 nigel 1.1 *
5 gbeauche 1.3 * Basilisk II (C) 1997-2005 Christian Bauer
6 nigel 1.1 *
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 nigel 1.4
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 nigel 1.1 #include "prefs.h"
33 nigel 1.4 #include "user_strings.h"
34 nigel 1.1 #include "audio.h"
35     #include "audio_defs.h"
36 nigel 1.4 #include "MacOSX_sound_if.h"
37 nigel 1.1
38 nigel 1.5 #define DEBUG 0
39 nigel 1.1 #include "debug.h"
40    
41    
42 nigel 1.4 // 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 nigel 1.1
53     /*
54     * Initialization
55     */
56 nigel 1.4 static int audioInt(void);
57 nigel 1.1
58 nigel 1.4 static bool open_audio(void)
59 nigel 1.1 {
60 nigel 1.4 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 nigel 1.1
64 nigel 1.4 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 nigel 1.1
73 nigel 1.4 audio_open = true;
74     return true;
75     }
76 nigel 1.1
77 nigel 1.4 void AudioInit(void)
78     {
79 nigel 1.1 // Sound disabled in prefs? Then do nothing
80     if (PrefsFindBool("nosound"))
81     return;
82    
83 nigel 1.4 //audio_sample_sizes.push_back(8);
84     audio_sample_sizes.push_back(16);
85 nigel 1.1
86 nigel 1.4 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 nigel 1.1
93 nigel 1.4 // 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 nigel 1.1
98 nigel 1.4 AudioStatus.mixer = 0;
99     AudioStatus.num_sources = 0;
100     audio_component_flags = cmpWantsRegisterMessage | kStereoOut | k16BitOut;
101     audio_component_flags = 0;
102 nigel 1.1
103 nigel 1.4 open_audio();
104 nigel 1.1 }
105    
106    
107     /*
108     * Deinitialization
109     */
110    
111 nigel 1.4 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 nigel 1.1 void AudioExit(void)
125     {
126 nigel 1.4 // Close audio device
127     close_audio();
128 nigel 1.1 }
129    
130    
131     /*
132     * First source added, start audio stream
133     */
134    
135     void audio_enter_stream()
136     {
137 nigel 1.4 // Streaming thread is always running to avoid clicking noises
138 nigel 1.1 }
139    
140    
141     /*
142     * Last source removed, stop audio stream
143     */
144    
145     void audio_exit_stream()
146     {
147 nigel 1.4 // Streaming thread is always running to avoid clicking noises
148 nigel 1.1 }
149    
150    
151     /*
152     * MacOS audio interrupt, read next data block
153     */
154    
155     void AudioInterrupt(void)
156     {
157     D(bug("AudioInterrupt\n"));
158 nigel 1.4 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 nigel 1.1 }
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 nigel 1.4 close_audio();
204     audio_sample_rate_index = index;
205     return open_audio();
206 nigel 1.1 }
207    
208     bool audio_set_sample_size(int index)
209     {
210 nigel 1.4 close_audio();
211     audio_sample_size_index = index;
212     return open_audio();
213 nigel 1.1 }
214    
215     bool audio_set_channels(int index)
216     {
217 nigel 1.4 close_audio();
218     audio_channel_count_index = index;
219     return open_audio();
220 nigel 1.1 }
221    
222     /*
223 nigel 1.4 * 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 nigel 1.1 */
228     bool audio_get_main_mute(void)
229     {
230 nigel 1.4 return main_mute;
231 nigel 1.1 }
232    
233     uint32 audio_get_main_volume(void)
234     {
235     return 0x01000100;
236     }
237    
238     bool audio_get_speaker_mute(void)
239     {
240 nigel 1.4 return speaker_mute;
241 nigel 1.1 }
242    
243     uint32 audio_get_speaker_volume(void)
244     {
245     return 0x01000100;
246     }
247    
248     void audio_set_main_mute(bool mute)
249     {
250 nigel 1.4 main_mute = mute;
251 nigel 1.1 }
252    
253     void audio_set_main_volume(uint32 vol)
254     {
255     }
256    
257     void audio_set_speaker_mute(bool mute)
258     {
259 nigel 1.4 speaker_mute = mute;
260 nigel 1.1 }
261    
262     void audio_set_speaker_volume(uint32 vol)
263     {
264     }
265 nigel 1.4
266     static int audioInt(void)
267     {
268     SetInterruptFlag(INTFLAG_AUDIO);
269     TriggerInterrupt();
270     return 0;
271     }