40 |
|
#include "debug.h" |
41 |
|
|
42 |
|
|
43 |
+ |
// The currently selected audio parameters (indices in audio_sample_rates[] |
44 |
+ |
// etc. vectors) |
45 |
+ |
static int audio_sample_rate_index = 0; |
46 |
+ |
static int audio_sample_size_index = 0; |
47 |
+ |
static int audio_channel_count_index = 0; |
48 |
+ |
|
49 |
|
// Global variables |
50 |
|
static int audio_fd = -1; // fd from audio library |
51 |
|
static sem_t audio_irq_done_sem; // Signal from interrupt to streaming thread: data block read |
58 |
|
static bool stream_thread_active = false; // Flag: streaming thread installed |
59 |
|
static volatile bool stream_thread_cancel = false; // Flag: cancel streaming thread |
60 |
|
|
61 |
+ |
static bool current_main_mute = false; // Flag: output muted |
62 |
+ |
static bool current_speaker_mute = false; // Flag: speaker muted |
63 |
+ |
static uint32 current_main_volume = 0; // Output volume |
64 |
+ |
static uint32 current_speaker_volume = 0; // Speaker volume |
65 |
+ |
|
66 |
|
// IRIX libaudio control structures |
67 |
|
static ALconfig config; |
68 |
|
static ALport port; |
70 |
|
|
71 |
|
// Prototypes |
72 |
|
static void *stream_func(void *arg); |
73 |
+ |
static uint32 read_volume(void); |
74 |
+ |
static bool read_mute(void); |
75 |
+ |
static void set_mute(bool mute); |
76 |
|
|
77 |
|
|
78 |
|
/* |
82 |
|
// Set AudioStatus to reflect current audio stream format |
83 |
|
static void set_audio_status_format(void) |
84 |
|
{ |
85 |
< |
AudioStatus.sample_rate = audio_sample_rates[0]; |
86 |
< |
AudioStatus.sample_size = audio_sample_sizes[0]; |
87 |
< |
AudioStatus.channels = audio_channel_counts[0]; |
85 |
> |
AudioStatus.sample_rate = audio_sample_rates[audio_sample_rate_index]; |
86 |
> |
AudioStatus.sample_size = audio_sample_sizes[audio_sample_size_index]; |
87 |
> |
AudioStatus.channels = audio_channel_counts[audio_channel_count_index]; |
88 |
|
} |
89 |
|
|
90 |
< |
// Init libaudio, returns false on error |
77 |
< |
bool audio_init_al(void) |
90 |
> |
bool open_audio(void) |
91 |
|
{ |
92 |
|
ALpv pv[2]; |
93 |
|
|
94 |
|
printf("Using libaudio audio output\n"); |
95 |
|
|
96 |
< |
// Try to open the audio library |
96 |
> |
// Get supported sample formats |
97 |
> |
|
98 |
> |
if (audio_sample_sizes.empty()) { |
99 |
> |
// All sample sizes are supported |
100 |
> |
audio_sample_sizes.push_back(8); |
101 |
> |
audio_sample_sizes.push_back(16); |
102 |
> |
|
103 |
> |
// Assume at least two channels are supported. Some IRIX boxes |
104 |
> |
// can do 4 or more... MacOS only handles up to 2. |
105 |
> |
audio_channel_counts.push_back(1); |
106 |
> |
audio_channel_counts.push_back(2); |
107 |
> |
|
108 |
> |
if (audio_sample_sizes.empty() || audio_channel_counts.empty()) { |
109 |
> |
WarningAlert(GetString(STR_AUDIO_FORMAT_WARN)); |
110 |
> |
alClosePort(port); |
111 |
> |
audio_fd = -1; |
112 |
> |
return false; |
113 |
> |
} |
114 |
> |
|
115 |
> |
audio_sample_rates.push_back( 8000 << 16); |
116 |
> |
audio_sample_rates.push_back(11025 << 16); |
117 |
> |
audio_sample_rates.push_back(22050 << 16); |
118 |
> |
audio_sample_rates.push_back(44100 << 16); |
119 |
> |
|
120 |
> |
// Default to highest supported values |
121 |
> |
audio_sample_rate_index = audio_sample_rates.size() - 1; |
122 |
> |
audio_sample_size_index = audio_sample_sizes.size() - 1; |
123 |
> |
audio_channel_count_index = audio_channel_counts.size() - 1; |
124 |
> |
} |
125 |
> |
|
126 |
> |
// Set the sample format |
127 |
|
|
128 |
+ |
D(bug("Size %d, channels %d, rate %d\n", |
129 |
+ |
audio_sample_sizes[audio_sample_size_index], |
130 |
+ |
audio_channel_counts[audio_channel_count_index], |
131 |
+ |
audio_sample_rates[audio_sample_rate_index] >> 16)); |
132 |
|
config = alNewConfig(); |
133 |
|
alSetSampFmt(config, AL_SAMPFMT_TWOSCOMP); |
134 |
< |
alSetWidth(config, AL_SAMPLE_16); |
135 |
< |
alSetChannels(config, 2); // stereo |
134 |
> |
if (audio_sample_sizes[audio_sample_size_index] == 8) { |
135 |
> |
alSetWidth(config, AL_SAMPLE_8); |
136 |
> |
} |
137 |
> |
else { |
138 |
> |
alSetWidth(config, AL_SAMPLE_16); |
139 |
> |
} |
140 |
> |
alSetChannels(config, audio_channel_counts[audio_channel_count_index]); |
141 |
|
alSetDevice(config, AL_DEFAULT_OUTPUT); // Allow selecting via prefs? |
142 |
|
|
143 |
+ |
// Try to open the audio library |
144 |
+ |
|
145 |
|
port = alOpenPort("BasiliskII", "w", config); |
146 |
|
if (port == NULL) { |
147 |
|
fprintf(stderr, "ERROR: Cannot open audio port: %s\n", |
148 |
|
alGetErrorString(oserror())); |
149 |
+ |
WarningAlert(GetString(STR_NO_AUDIO_WARN)); |
150 |
|
return false; |
151 |
|
} |
152 |
< |
|
152 |
> |
|
153 |
|
// Set the sample rate |
154 |
|
|
155 |
|
pv[0].param = AL_RATE; |
156 |
< |
pv[0].value.ll = alDoubleToFixed(audio_sample_rates[0] >> 16); |
156 |
> |
pv[0].value.ll = alDoubleToFixed(audio_sample_rates[audio_sample_rate_index] >> 16); |
157 |
|
pv[1].param = AL_MASTER_CLOCK; |
158 |
|
pv[1].value.i = AL_CRYSTAL_MCLK_TYPE; |
159 |
|
if (alSetParams(AL_DEFAULT_OUTPUT, pv, 2) < 0) { |
163 |
|
return false; |
164 |
|
} |
165 |
|
|
111 |
– |
// TODO: list all supported sample formats? |
112 |
– |
|
113 |
– |
// Set AudioStatus again because we now know more about the sound |
114 |
– |
// system's capabilities |
115 |
– |
set_audio_status_format(); |
116 |
– |
|
166 |
|
// Compute sound buffer size and libaudio refill point |
167 |
|
|
168 |
|
config = alGetConfig(port); |
173 |
|
alClosePort(port); |
174 |
|
return false; |
175 |
|
} |
176 |
< |
D(bug("alGetQueueSize %d\n", audio_frames_per_block)); |
176 |
> |
D(bug("alGetQueueSize %d, width %d, channels %d\n", |
177 |
> |
audio_frames_per_block, |
178 |
> |
alGetWidth(config), |
179 |
> |
alGetChannels(config))); |
180 |
> |
|
181 |
> |
// Put a limit on the Mac sound buffer size, to decrease delay |
182 |
> |
#define AUDIO_BUFFER_MSEC 50 // milliseconds of sound to buffer |
183 |
> |
int target_frames_per_block = |
184 |
> |
(audio_sample_rates[audio_sample_rate_index] >> 16) * |
185 |
> |
AUDIO_BUFFER_MSEC / 1000; |
186 |
> |
if (audio_frames_per_block > target_frames_per_block) |
187 |
> |
audio_frames_per_block = target_frames_per_block; |
188 |
> |
D(bug("frames per block %d\n", audio_frames_per_block)); |
189 |
|
|
190 |
|
alZeroFrames(port, audio_frames_per_block); // so we don't underflow |
191 |
|
|
192 |
< |
// Put a limit on the Mac sound buffer size, to decrease delay |
193 |
< |
if (audio_frames_per_block > 2048) |
194 |
< |
audio_frames_per_block = 2048; |
134 |
< |
// Try to keep the buffer pretty full. 5000 samples of slack works well. |
135 |
< |
sound_buffer_fill_point = alGetQueueSize(config) - 5000; |
192 |
> |
// Try to keep the buffer pretty full |
193 |
> |
sound_buffer_fill_point = alGetQueueSize(config) - |
194 |
> |
2 * audio_frames_per_block; |
195 |
|
if (sound_buffer_fill_point < 0) |
196 |
|
sound_buffer_fill_point = alGetQueueSize(config) / 3; |
197 |
|
D(bug("fill point %d\n", sound_buffer_fill_point)); |
198 |
|
|
199 |
< |
sound_buffer_size = (AudioStatus.sample_size >> 3) * AudioStatus.channels * audio_frames_per_block; |
199 |
> |
sound_buffer_size = (audio_sample_sizes[audio_sample_size_index] >> 3) * |
200 |
> |
audio_channel_counts[audio_channel_count_index] * |
201 |
> |
audio_frames_per_block; |
202 |
> |
set_audio_status_format(); |
203 |
|
|
204 |
|
// Get a file descriptor we can select() on |
205 |
|
|
211 |
|
return false; |
212 |
|
} |
213 |
|
|
214 |
< |
return true; |
215 |
< |
} |
214 |
> |
// Initialize volume, mute settings |
215 |
> |
current_main_volume = current_speaker_volume = read_volume(); |
216 |
> |
current_main_mute = current_speaker_mute = read_mute(); |
217 |
|
|
218 |
|
|
219 |
< |
/* |
220 |
< |
* Initialization |
221 |
< |
*/ |
219 |
> |
// Start streaming thread |
220 |
> |
Set_pthread_attr(&stream_thread_attr, 0); |
221 |
> |
stream_thread_active = (pthread_create(&stream_thread, &stream_thread_attr, stream_func, NULL) == 0); |
222 |
> |
|
223 |
> |
// Everything went fine |
224 |
> |
audio_open = true; |
225 |
> |
return true; |
226 |
> |
} |
227 |
|
|
228 |
|
void AudioInit(void) |
229 |
|
{ |
230 |
< |
// Init audio status (defaults) and feature flags |
231 |
< |
audio_sample_rates.push_back(44100 << 16); |
232 |
< |
audio_sample_sizes.push_back(16); |
233 |
< |
audio_channel_counts.push_back(2); |
166 |
< |
set_audio_status_format(); |
230 |
> |
// Init audio status (reasonable defaults) and feature flags |
231 |
> |
AudioStatus.sample_rate = 44100 << 16; |
232 |
> |
AudioStatus.sample_size = 16; |
233 |
> |
AudioStatus.channels = 2; |
234 |
|
AudioStatus.mixer = 0; |
235 |
|
AudioStatus.num_sources = 0; |
236 |
|
audio_component_flags = cmpWantsRegisterMessage | kStereoOut | k16BitOut; |
239 |
|
if (PrefsFindBool("nosound")) |
240 |
|
return; |
241 |
|
|
175 |
– |
// Try to open audio library |
176 |
– |
if (!audio_init_al()) |
177 |
– |
return; |
178 |
– |
|
242 |
|
// Init semaphore |
243 |
|
if (sem_init(&audio_irq_done_sem, 0, 0) < 0) |
244 |
|
return; |
245 |
|
sem_inited = true; |
246 |
|
|
247 |
< |
// Start streaming thread |
248 |
< |
Set_pthread_attr(&stream_thread_attr, 0); |
186 |
< |
stream_thread_active = (pthread_create(&stream_thread, &stream_thread_attr, stream_func, NULL) == 0); |
187 |
< |
|
188 |
< |
// Everything OK |
189 |
< |
audio_open = true; |
247 |
> |
// Open and initialize audio device |
248 |
> |
open_audio(); |
249 |
|
} |
250 |
|
|
251 |
|
|
253 |
|
* Deinitialization |
254 |
|
*/ |
255 |
|
|
256 |
< |
void AudioExit(void) |
256 |
> |
static void close_audio(void) |
257 |
|
{ |
258 |
|
// Stop stream and delete semaphore |
259 |
|
if (stream_thread_active) { |
263 |
|
#endif |
264 |
|
pthread_join(stream_thread, NULL); |
265 |
|
stream_thread_active = false; |
266 |
+ |
stream_thread_cancel = false; |
267 |
|
} |
208 |
– |
if (sem_inited) |
209 |
– |
sem_destroy(&audio_irq_done_sem); |
268 |
|
|
269 |
|
// Close audio library |
270 |
|
alClosePort(port); |
271 |
+ |
|
272 |
+ |
audio_open = false; |
273 |
+ |
} |
274 |
+ |
|
275 |
+ |
void AudioExit(void) |
276 |
+ |
{ |
277 |
+ |
// Close audio device |
278 |
+ |
close_audio(); |
279 |
+ |
|
280 |
+ |
// Delete semaphore |
281 |
+ |
if (sem_inited) { |
282 |
+ |
sem_destroy(&audio_irq_done_sem); |
283 |
+ |
sem_inited = false; |
284 |
+ |
} |
285 |
|
} |
286 |
|
|
287 |
|
|
311 |
|
|
312 |
|
static void *stream_func(void *arg) |
313 |
|
{ |
314 |
< |
int16 *last_buffer = new int16[sound_buffer_size / 2]; |
314 |
> |
int32 *last_buffer = new int32[sound_buffer_size / 4]; |
315 |
|
fd_set audio_fdset; |
316 |
|
int numfds, was_error; |
317 |
|
|
329 |
|
sem_wait(&audio_irq_done_sem); |
330 |
|
D(bug("stream: ack received\n")); |
331 |
|
|
260 |
– |
uint32 apple_stream_info; // Mac address of SoundComponentData struct describing next buffer |
332 |
|
// Get size of audio data |
333 |
< |
apple_stream_info = ReadMacInt32(audio_data + adatStreamInfo); |
334 |
< |
|
335 |
< |
if (apple_stream_info) { |
333 |
> |
uint32 apple_stream_info = ReadMacInt32(audio_data + adatStreamInfo); |
334 |
> |
if (!current_main_mute && |
335 |
> |
!current_speaker_mute && |
336 |
> |
apple_stream_info) { |
337 |
|
int work_size = ReadMacInt32(apple_stream_info + scd_sampleCount) * (AudioStatus.sample_size >> 3) * AudioStatus.channels; |
338 |
|
D(bug("stream: work_size %d\n", work_size)); |
339 |
|
if (work_size > sound_buffer_size) |
341 |
|
if (work_size == 0) |
342 |
|
goto silence; |
343 |
|
|
344 |
< |
// Send data to audio library |
345 |
< |
if (work_size == sound_buffer_size) |
344 |
> |
// Send data to audio library. Convert 8-bit data |
345 |
> |
// unsigned->signed, using same algorithm as audio_amiga.cpp. |
346 |
> |
// It works fine for 8-bit mono, but not stereo. |
347 |
> |
if (AudioStatus.sample_size == 8) { |
348 |
> |
uint32 *p = (uint32 *)Mac2HostAddr(ReadMacInt32(apple_stream_info + scd_buffer)); |
349 |
> |
uint32 *q = (uint32 *)last_buffer; |
350 |
> |
int r = work_size >> 2; |
351 |
> |
// XXX not quite right.... |
352 |
> |
while (r--) |
353 |
> |
*q++ = *p++ ^ 0x80808080; |
354 |
> |
if (work_size != sound_buffer_size) |
355 |
> |
memset((uint8 *)last_buffer + work_size, silence_byte, sound_buffer_size - work_size); |
356 |
> |
alWriteFrames(port, last_buffer, audio_frames_per_block); |
357 |
> |
} |
358 |
> |
else if (work_size == sound_buffer_size) |
359 |
|
alWriteFrames(port, Mac2HostAddr(ReadMacInt32(apple_stream_info + scd_buffer)), audio_frames_per_block); |
360 |
|
else { |
361 |
|
// Last buffer |
399 |
|
|
400 |
|
|
401 |
|
/* |
402 |
+ |
* Read or set the current output volume using the audio library |
403 |
+ |
*/ |
404 |
+ |
|
405 |
+ |
static uint32 read_volume(void) |
406 |
+ |
{ |
407 |
+ |
ALpv x[2]; |
408 |
+ |
ALfixed gain[8]; |
409 |
+ |
double maxgain, mingain; |
410 |
+ |
ALparamInfo pi; |
411 |
+ |
uint32 ret = 0x01000100; // default, maximum value |
412 |
+ |
int dev = alGetDevice(config); |
413 |
+ |
|
414 |
+ |
// Fetch the maximum and minimum gain settings |
415 |
+ |
|
416 |
+ |
alGetParamInfo(dev, AL_GAIN, &pi); |
417 |
+ |
maxgain = alFixedToDouble(pi.max.ll); |
418 |
+ |
mingain = alFixedToDouble(pi.min.ll); |
419 |
+ |
// printf("maxgain = %lf dB, mingain = %lf dB\n", maxgain, mingain); |
420 |
+ |
|
421 |
+ |
// Get the current gain values |
422 |
+ |
|
423 |
+ |
x[0].param = AL_GAIN; |
424 |
+ |
x[0].value.ptr = gain; |
425 |
+ |
x[0].sizeIn = sizeof(gain) / sizeof(gain[0]); |
426 |
+ |
x[1].param = AL_CHANNELS; |
427 |
+ |
if (alGetParams(dev, x, 2) < 0) { |
428 |
+ |
printf("alGetParams failed: %s\n", alGetErrorString(oserror())); |
429 |
+ |
} |
430 |
+ |
else { |
431 |
+ |
if (x[0].sizeOut < 0) { |
432 |
+ |
printf("AL_GAIN was an unrecognized parameter\n"); |
433 |
+ |
} |
434 |
+ |
else { |
435 |
+ |
double v; |
436 |
+ |
uint32 left, right; |
437 |
+ |
|
438 |
+ |
// Left |
439 |
+ |
v = alFixedToDouble(gain[0]); |
440 |
+ |
if (v < mingain) |
441 |
+ |
v = mingain; // handle gain == -inf |
442 |
+ |
v = (v - mingain) / (maxgain - mingain); // scale to 0..1 |
443 |
+ |
left = (uint32)(v * (double)256); // convert to 8.8 fixed point |
444 |
+ |
|
445 |
+ |
// Right |
446 |
+ |
if (x[0].sizeOut <= 1) { // handle a mono interface |
447 |
+ |
right = left; |
448 |
+ |
} |
449 |
+ |
else { |
450 |
+ |
v = alFixedToDouble(gain[1]); |
451 |
+ |
if (v < mingain) |
452 |
+ |
v = mingain; // handle gain == -inf |
453 |
+ |
v = (v - mingain) / (maxgain - mingain); // scale to 0..1 |
454 |
+ |
right = (uint32)(v * (double)256); // convert to 8.8 fixed point |
455 |
+ |
} |
456 |
+ |
|
457 |
+ |
ret = (left << 16) | right; |
458 |
+ |
} |
459 |
+ |
} |
460 |
+ |
|
461 |
+ |
return ret; |
462 |
+ |
} |
463 |
+ |
|
464 |
+ |
static void set_volume(uint32 vol) |
465 |
+ |
{ |
466 |
+ |
ALpv x[1]; |
467 |
+ |
ALfixed gain[2]; // left and right |
468 |
+ |
double maxgain, mingain; |
469 |
+ |
ALparamInfo pi; |
470 |
+ |
int dev = alGetDevice(config); |
471 |
+ |
|
472 |
+ |
// Fetch the maximum and minimum gain settings |
473 |
+ |
|
474 |
+ |
alGetParamInfo(dev, AL_GAIN, &pi); |
475 |
+ |
maxgain = alFixedToDouble(pi.max.ll); |
476 |
+ |
mingain = alFixedToDouble(pi.min.ll); |
477 |
+ |
|
478 |
+ |
// Set the new gain values |
479 |
+ |
|
480 |
+ |
x[0].param = AL_GAIN; |
481 |
+ |
x[0].value.ptr = gain; |
482 |
+ |
x[0].sizeIn = sizeof(gain) / sizeof(gain[0]); |
483 |
+ |
|
484 |
+ |
uint32 left = vol >> 16; |
485 |
+ |
uint32 right = vol & 0xffff; |
486 |
+ |
double lv, rv; |
487 |
+ |
|
488 |
+ |
if (left == 0 && pi.specialVals & AL_NEG_INFINITY_BIT) { |
489 |
+ |
lv = AL_NEG_INFINITY; |
490 |
+ |
} |
491 |
+ |
else { |
492 |
+ |
lv = ((double)left / 256) * (maxgain - mingain) + mingain; |
493 |
+ |
} |
494 |
+ |
|
495 |
+ |
if (right == 0 && pi.specialVals & AL_NEG_INFINITY_BIT) { |
496 |
+ |
rv = AL_NEG_INFINITY; |
497 |
+ |
} |
498 |
+ |
else { |
499 |
+ |
rv = ((double)right / 256) * (maxgain - mingain) + mingain; |
500 |
+ |
} |
501 |
+ |
|
502 |
+ |
D(bug("set_volume: left=%lf dB, right=%lf dB\n", lv, rv)); |
503 |
+ |
|
504 |
+ |
gain[0] = alDoubleToFixed(lv); |
505 |
+ |
gain[1] = alDoubleToFixed(rv); |
506 |
+ |
|
507 |
+ |
if (alSetParams(dev, x, 1) < 0) { |
508 |
+ |
printf("alSetParams failed: %s\n", alGetErrorString(oserror())); |
509 |
+ |
} |
510 |
+ |
} |
511 |
+ |
|
512 |
+ |
|
513 |
+ |
/* |
514 |
+ |
* Read or set the mute setting using the audio library |
515 |
+ |
*/ |
516 |
+ |
|
517 |
+ |
static bool read_mute(void) |
518 |
+ |
{ |
519 |
+ |
bool ret; |
520 |
+ |
int dev = alGetDevice(config); |
521 |
+ |
ALpv x; |
522 |
+ |
x.param = AL_MUTE; |
523 |
+ |
|
524 |
+ |
if (alGetParams(dev, &x, 1) < 0) { |
525 |
+ |
printf("alSetParams failed: %s\n", alGetErrorString(oserror())); |
526 |
+ |
return current_main_mute; // Or just return false? |
527 |
+ |
} |
528 |
+ |
|
529 |
+ |
ret = x.value.i; |
530 |
+ |
|
531 |
+ |
D(bug("read_mute: mute=%d\n", ret)); |
532 |
+ |
return ret; |
533 |
+ |
} |
534 |
+ |
|
535 |
+ |
static void set_mute(bool mute) |
536 |
+ |
{ |
537 |
+ |
D(bug("set_mute: mute=%ld\n", mute)); |
538 |
+ |
|
539 |
+ |
int dev = alGetDevice(config); |
540 |
+ |
ALpv x; |
541 |
+ |
x.param = AL_MUTE; |
542 |
+ |
x.value.i = mute; |
543 |
+ |
|
544 |
+ |
if (alSetParams(dev, &x, 1) < 0) { |
545 |
+ |
printf("alSetParams failed: %s\n", alGetErrorString(oserror())); |
546 |
+ |
} |
547 |
+ |
} |
548 |
+ |
|
549 |
+ |
|
550 |
+ |
|
551 |
+ |
/* |
552 |
|
* MacOS audio interrupt, read next data block |
553 |
|
*/ |
554 |
|
|
574 |
|
|
575 |
|
/* |
576 |
|
* Set sampling parameters |
577 |
< |
* "index" is an index into the audio_sample_rates[] etc. arrays |
577 |
> |
* "index" is an index into the audio_sample_rates[] etc. vectors |
578 |
|
* It is guaranteed that AudioStatus.num_sources == 0 |
579 |
|
*/ |
580 |
|
|
581 |
|
bool audio_set_sample_rate(int index) |
582 |
|
{ |
583 |
< |
return true; |
583 |
> |
close_audio(); |
584 |
> |
audio_sample_rate_index = index; |
585 |
> |
return open_audio(); |
586 |
|
} |
587 |
|
|
588 |
|
bool audio_set_sample_size(int index) |
589 |
|
{ |
590 |
< |
return true; |
590 |
> |
close_audio(); |
591 |
> |
audio_sample_size_index = index; |
592 |
> |
return open_audio(); |
593 |
|
} |
594 |
|
|
595 |
|
bool audio_set_channels(int index) |
596 |
|
{ |
597 |
< |
return true; |
597 |
> |
close_audio(); |
598 |
> |
audio_channel_count_index = index; |
599 |
> |
return open_audio(); |
600 |
|
} |
601 |
|
|
602 |
|
|
608 |
|
|
609 |
|
bool audio_get_main_mute(void) |
610 |
|
{ |
611 |
< |
return false; |
611 |
> |
D(bug("audio_get_main_mute: mute=%ld\n", current_main_mute)); |
612 |
> |
|
613 |
> |
return current_main_mute; |
614 |
|
} |
615 |
|
|
616 |
|
uint32 audio_get_main_volume(void) |
617 |
|
{ |
618 |
< |
return 0x01000100; |
618 |
> |
uint32 ret = current_main_volume; |
619 |
> |
|
620 |
> |
D(bug("audio_get_main_volume: vol=0x%x\n", ret)); |
621 |
> |
|
622 |
> |
return ret; |
623 |
|
} |
624 |
|
|
625 |
|
bool audio_get_speaker_mute(void) |
626 |
|
{ |
627 |
< |
return false; |
627 |
> |
D(bug("audio_get_speaker_mute: mute=%ld\n", current_speaker_mute)); |
628 |
> |
|
629 |
> |
return current_speaker_mute; |
630 |
|
} |
631 |
|
|
632 |
|
uint32 audio_get_speaker_volume(void) |
633 |
|
{ |
634 |
< |
return 0x01000100; |
634 |
> |
uint32 ret = current_speaker_volume; |
635 |
> |
|
636 |
> |
D(bug("audio_get_speaker_volume: vol=0x%x\n", ret)); |
637 |
> |
|
638 |
> |
return ret; |
639 |
|
} |
640 |
|
|
641 |
|
void audio_set_main_mute(bool mute) |
642 |
|
{ |
643 |
+ |
D(bug("audio_set_main_mute: mute=%ld\n", mute)); |
644 |
+ |
|
645 |
+ |
if (mute != current_main_mute) { |
646 |
+ |
current_main_mute = mute; |
647 |
+ |
} |
648 |
+ |
|
649 |
+ |
set_mute(current_main_mute); |
650 |
|
} |
651 |
|
|
652 |
|
void audio_set_main_volume(uint32 vol) |
653 |
|
{ |
654 |
+ |
|
655 |
+ |
D(bug("audio_set_main_volume: vol=%x\n", vol)); |
656 |
+ |
|
657 |
+ |
current_main_volume = vol; |
658 |
+ |
|
659 |
+ |
set_volume(vol); |
660 |
|
} |
661 |
|
|
662 |
|
void audio_set_speaker_mute(bool mute) |
663 |
|
{ |
664 |
+ |
D(bug("audio_set_speaker_mute: mute=%ld\n", mute)); |
665 |
+ |
|
666 |
+ |
if (mute != current_speaker_mute) { |
667 |
+ |
current_speaker_mute = mute; |
668 |
+ |
} |
669 |
+ |
|
670 |
+ |
set_mute(current_speaker_mute); |
671 |
|
} |
672 |
|
|
673 |
|
void audio_set_speaker_volume(uint32 vol) |
674 |
|
{ |
675 |
+ |
D(bug("audio_set_speaker_volume: vol=%x\n", vol)); |
676 |
+ |
|
677 |
+ |
current_speaker_volume = vol; |
678 |
+ |
|
679 |
+ |
set_volume(vol); |
680 |
|
} |