mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-12-18 17:31:08 +00:00
added format switching and other improvements [Brian Johnson]
This commit is contained in:
parent
0074b3346e
commit
16b21014ef
@ -40,6 +40,12 @@
|
|||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
|
|
||||||
|
// The currently selected audio parameters (indices in audio_sample_rates[]
|
||||||
|
// etc. vectors)
|
||||||
|
static int audio_sample_rate_index = 0;
|
||||||
|
static int audio_sample_size_index = 0;
|
||||||
|
static int audio_channel_count_index = 0;
|
||||||
|
|
||||||
// Global variables
|
// Global variables
|
||||||
static int audio_fd = -1; // fd from audio library
|
static int audio_fd = -1; // fd from audio library
|
||||||
static sem_t audio_irq_done_sem; // Signal from interrupt to streaming thread: data block read
|
static sem_t audio_irq_done_sem; // Signal from interrupt to streaming thread: data block read
|
||||||
@ -52,6 +58,11 @@ static pthread_attr_t stream_thread_attr; // Streaming thread attributes
|
|||||||
static bool stream_thread_active = false; // Flag: streaming thread installed
|
static bool stream_thread_active = false; // Flag: streaming thread installed
|
||||||
static volatile bool stream_thread_cancel = false; // Flag: cancel streaming thread
|
static volatile bool stream_thread_cancel = false; // Flag: cancel streaming thread
|
||||||
|
|
||||||
|
static bool current_main_mute = false; // Flag: output muted
|
||||||
|
static bool current_speaker_mute = false; // Flag: speaker muted
|
||||||
|
static uint32 current_main_volume = 0; // Output volume
|
||||||
|
static uint32 current_speaker_volume = 0; // Speaker volume
|
||||||
|
|
||||||
// IRIX libaudio control structures
|
// IRIX libaudio control structures
|
||||||
static ALconfig config;
|
static ALconfig config;
|
||||||
static ALport port;
|
static ALport port;
|
||||||
@ -59,6 +70,9 @@ static ALport port;
|
|||||||
|
|
||||||
// Prototypes
|
// Prototypes
|
||||||
static void *stream_func(void *arg);
|
static void *stream_func(void *arg);
|
||||||
|
static uint32 read_volume(void);
|
||||||
|
static bool read_mute(void);
|
||||||
|
static void set_mute(bool mute);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -68,37 +82,78 @@ static void *stream_func(void *arg);
|
|||||||
// Set AudioStatus to reflect current audio stream format
|
// Set AudioStatus to reflect current audio stream format
|
||||||
static void set_audio_status_format(void)
|
static void set_audio_status_format(void)
|
||||||
{
|
{
|
||||||
AudioStatus.sample_rate = audio_sample_rates[0];
|
AudioStatus.sample_rate = audio_sample_rates[audio_sample_rate_index];
|
||||||
AudioStatus.sample_size = audio_sample_sizes[0];
|
AudioStatus.sample_size = audio_sample_sizes[audio_sample_size_index];
|
||||||
AudioStatus.channels = audio_channel_counts[0];
|
AudioStatus.channels = audio_channel_counts[audio_channel_count_index];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init libaudio, returns false on error
|
bool open_audio(void)
|
||||||
bool audio_init_al(void)
|
|
||||||
{
|
{
|
||||||
ALpv pv[2];
|
ALpv pv[2];
|
||||||
|
|
||||||
printf("Using libaudio audio output\n");
|
printf("Using libaudio audio output\n");
|
||||||
|
|
||||||
// Try to open the audio library
|
// Get supported sample formats
|
||||||
|
|
||||||
|
if (audio_sample_sizes.empty()) {
|
||||||
|
// All sample sizes are supported
|
||||||
|
audio_sample_sizes.push_back(8);
|
||||||
|
audio_sample_sizes.push_back(16);
|
||||||
|
|
||||||
|
// Assume at least two channels are supported. Some IRIX boxes
|
||||||
|
// can do 4 or more... MacOS only handles up to 2.
|
||||||
|
audio_channel_counts.push_back(1);
|
||||||
|
audio_channel_counts.push_back(2);
|
||||||
|
|
||||||
|
if (audio_sample_sizes.empty() || audio_channel_counts.empty()) {
|
||||||
|
WarningAlert(GetString(STR_AUDIO_FORMAT_WARN));
|
||||||
|
alClosePort(port);
|
||||||
|
audio_fd = -1;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
audio_sample_rates.push_back( 8000 << 16);
|
||||||
|
audio_sample_rates.push_back(11025 << 16);
|
||||||
|
audio_sample_rates.push_back(22050 << 16);
|
||||||
|
audio_sample_rates.push_back(44100 << 16);
|
||||||
|
|
||||||
|
// Default to highest supported values
|
||||||
|
audio_sample_rate_index = audio_sample_rates.size() - 1;
|
||||||
|
audio_sample_size_index = audio_sample_sizes.size() - 1;
|
||||||
|
audio_channel_count_index = audio_channel_counts.size() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the sample format
|
||||||
|
|
||||||
|
D(bug("Size %d, channels %d, rate %d\n",
|
||||||
|
audio_sample_sizes[audio_sample_size_index],
|
||||||
|
audio_channel_counts[audio_channel_count_index],
|
||||||
|
audio_sample_rates[audio_sample_rate_index] >> 16));
|
||||||
config = alNewConfig();
|
config = alNewConfig();
|
||||||
alSetSampFmt(config, AL_SAMPFMT_TWOSCOMP);
|
alSetSampFmt(config, AL_SAMPFMT_TWOSCOMP);
|
||||||
|
if (audio_sample_sizes[audio_sample_size_index] == 8) {
|
||||||
|
alSetWidth(config, AL_SAMPLE_8);
|
||||||
|
}
|
||||||
|
else {
|
||||||
alSetWidth(config, AL_SAMPLE_16);
|
alSetWidth(config, AL_SAMPLE_16);
|
||||||
alSetChannels(config, 2); // stereo
|
}
|
||||||
|
alSetChannels(config, audio_channel_counts[audio_channel_count_index]);
|
||||||
alSetDevice(config, AL_DEFAULT_OUTPUT); // Allow selecting via prefs?
|
alSetDevice(config, AL_DEFAULT_OUTPUT); // Allow selecting via prefs?
|
||||||
|
|
||||||
|
// Try to open the audio library
|
||||||
|
|
||||||
port = alOpenPort("BasiliskII", "w", config);
|
port = alOpenPort("BasiliskII", "w", config);
|
||||||
if (port == NULL) {
|
if (port == NULL) {
|
||||||
fprintf(stderr, "ERROR: Cannot open audio port: %s\n",
|
fprintf(stderr, "ERROR: Cannot open audio port: %s\n",
|
||||||
alGetErrorString(oserror()));
|
alGetErrorString(oserror()));
|
||||||
|
WarningAlert(GetString(STR_NO_AUDIO_WARN));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the sample rate
|
// Set the sample rate
|
||||||
|
|
||||||
pv[0].param = AL_RATE;
|
pv[0].param = AL_RATE;
|
||||||
pv[0].value.ll = alDoubleToFixed(audio_sample_rates[0] >> 16);
|
pv[0].value.ll = alDoubleToFixed(audio_sample_rates[audio_sample_rate_index] >> 16);
|
||||||
pv[1].param = AL_MASTER_CLOCK;
|
pv[1].param = AL_MASTER_CLOCK;
|
||||||
pv[1].value.i = AL_CRYSTAL_MCLK_TYPE;
|
pv[1].value.i = AL_CRYSTAL_MCLK_TYPE;
|
||||||
if (alSetParams(AL_DEFAULT_OUTPUT, pv, 2) < 0) {
|
if (alSetParams(AL_DEFAULT_OUTPUT, pv, 2) < 0) {
|
||||||
@ -108,12 +163,6 @@ bool audio_init_al(void)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: list all supported sample formats?
|
|
||||||
|
|
||||||
// Set AudioStatus again because we now know more about the sound
|
|
||||||
// system's capabilities
|
|
||||||
set_audio_status_format();
|
|
||||||
|
|
||||||
// Compute sound buffer size and libaudio refill point
|
// Compute sound buffer size and libaudio refill point
|
||||||
|
|
||||||
config = alGetConfig(port);
|
config = alGetConfig(port);
|
||||||
@ -124,20 +173,33 @@ bool audio_init_al(void)
|
|||||||
alClosePort(port);
|
alClosePort(port);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
D(bug("alGetQueueSize %d\n", audio_frames_per_block));
|
D(bug("alGetQueueSize %d, width %d, channels %d\n",
|
||||||
|
audio_frames_per_block,
|
||||||
|
alGetWidth(config),
|
||||||
|
alGetChannels(config)));
|
||||||
|
|
||||||
|
// Put a limit on the Mac sound buffer size, to decrease delay
|
||||||
|
#define AUDIO_BUFFER_MSEC 50 // milliseconds of sound to buffer
|
||||||
|
int target_frames_per_block =
|
||||||
|
(audio_sample_rates[audio_sample_rate_index] >> 16) *
|
||||||
|
AUDIO_BUFFER_MSEC / 1000;
|
||||||
|
if (audio_frames_per_block > target_frames_per_block)
|
||||||
|
audio_frames_per_block = target_frames_per_block;
|
||||||
|
D(bug("frames per block %d\n", audio_frames_per_block));
|
||||||
|
|
||||||
alZeroFrames(port, audio_frames_per_block); // so we don't underflow
|
alZeroFrames(port, audio_frames_per_block); // so we don't underflow
|
||||||
|
|
||||||
// Put a limit on the Mac sound buffer size, to decrease delay
|
// Try to keep the buffer pretty full
|
||||||
if (audio_frames_per_block > 2048)
|
sound_buffer_fill_point = alGetQueueSize(config) -
|
||||||
audio_frames_per_block = 2048;
|
2 * audio_frames_per_block;
|
||||||
// Try to keep the buffer pretty full. 5000 samples of slack works well.
|
|
||||||
sound_buffer_fill_point = alGetQueueSize(config) - 5000;
|
|
||||||
if (sound_buffer_fill_point < 0)
|
if (sound_buffer_fill_point < 0)
|
||||||
sound_buffer_fill_point = alGetQueueSize(config) / 3;
|
sound_buffer_fill_point = alGetQueueSize(config) / 3;
|
||||||
D(bug("fill point %d\n", sound_buffer_fill_point));
|
D(bug("fill point %d\n", sound_buffer_fill_point));
|
||||||
|
|
||||||
sound_buffer_size = (AudioStatus.sample_size >> 3) * AudioStatus.channels * audio_frames_per_block;
|
sound_buffer_size = (audio_sample_sizes[audio_sample_size_index] >> 3) *
|
||||||
|
audio_channel_counts[audio_channel_count_index] *
|
||||||
|
audio_frames_per_block;
|
||||||
|
set_audio_status_format();
|
||||||
|
|
||||||
// Get a file descriptor we can select() on
|
// Get a file descriptor we can select() on
|
||||||
|
|
||||||
@ -149,21 +211,26 @@ bool audio_init_al(void)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialize volume, mute settings
|
||||||
|
current_main_volume = current_speaker_volume = read_volume();
|
||||||
|
current_main_mute = current_speaker_mute = read_mute();
|
||||||
|
|
||||||
|
|
||||||
|
// Start streaming thread
|
||||||
|
Set_pthread_attr(&stream_thread_attr, 0);
|
||||||
|
stream_thread_active = (pthread_create(&stream_thread, &stream_thread_attr, stream_func, NULL) == 0);
|
||||||
|
|
||||||
|
// Everything went fine
|
||||||
|
audio_open = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialization
|
|
||||||
*/
|
|
||||||
|
|
||||||
void AudioInit(void)
|
void AudioInit(void)
|
||||||
{
|
{
|
||||||
// Init audio status (defaults) and feature flags
|
// Init audio status (reasonable defaults) and feature flags
|
||||||
audio_sample_rates.push_back(44100 << 16);
|
AudioStatus.sample_rate = 44100 << 16;
|
||||||
audio_sample_sizes.push_back(16);
|
AudioStatus.sample_size = 16;
|
||||||
audio_channel_counts.push_back(2);
|
AudioStatus.channels = 2;
|
||||||
set_audio_status_format();
|
|
||||||
AudioStatus.mixer = 0;
|
AudioStatus.mixer = 0;
|
||||||
AudioStatus.num_sources = 0;
|
AudioStatus.num_sources = 0;
|
||||||
audio_component_flags = cmpWantsRegisterMessage | kStereoOut | k16BitOut;
|
audio_component_flags = cmpWantsRegisterMessage | kStereoOut | k16BitOut;
|
||||||
@ -172,21 +239,13 @@ void AudioInit(void)
|
|||||||
if (PrefsFindBool("nosound"))
|
if (PrefsFindBool("nosound"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Try to open audio library
|
|
||||||
if (!audio_init_al())
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Init semaphore
|
// Init semaphore
|
||||||
if (sem_init(&audio_irq_done_sem, 0, 0) < 0)
|
if (sem_init(&audio_irq_done_sem, 0, 0) < 0)
|
||||||
return;
|
return;
|
||||||
sem_inited = true;
|
sem_inited = true;
|
||||||
|
|
||||||
// Start streaming thread
|
// Open and initialize audio device
|
||||||
Set_pthread_attr(&stream_thread_attr, 0);
|
open_audio();
|
||||||
stream_thread_active = (pthread_create(&stream_thread, &stream_thread_attr, stream_func, NULL) == 0);
|
|
||||||
|
|
||||||
// Everything OK
|
|
||||||
audio_open = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -194,7 +253,7 @@ void AudioInit(void)
|
|||||||
* Deinitialization
|
* Deinitialization
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void AudioExit(void)
|
static void close_audio(void)
|
||||||
{
|
{
|
||||||
// Stop stream and delete semaphore
|
// Stop stream and delete semaphore
|
||||||
if (stream_thread_active) {
|
if (stream_thread_active) {
|
||||||
@ -204,12 +263,25 @@ void AudioExit(void)
|
|||||||
#endif
|
#endif
|
||||||
pthread_join(stream_thread, NULL);
|
pthread_join(stream_thread, NULL);
|
||||||
stream_thread_active = false;
|
stream_thread_active = false;
|
||||||
|
stream_thread_cancel = false;
|
||||||
}
|
}
|
||||||
if (sem_inited)
|
|
||||||
sem_destroy(&audio_irq_done_sem);
|
|
||||||
|
|
||||||
// Close audio library
|
// Close audio library
|
||||||
alClosePort(port);
|
alClosePort(port);
|
||||||
|
|
||||||
|
audio_open = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioExit(void)
|
||||||
|
{
|
||||||
|
// Close audio device
|
||||||
|
close_audio();
|
||||||
|
|
||||||
|
// Delete semaphore
|
||||||
|
if (sem_inited) {
|
||||||
|
sem_destroy(&audio_irq_done_sem);
|
||||||
|
sem_inited = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -239,7 +311,7 @@ void audio_exit_stream()
|
|||||||
|
|
||||||
static void *stream_func(void *arg)
|
static void *stream_func(void *arg)
|
||||||
{
|
{
|
||||||
int16 *last_buffer = new int16[sound_buffer_size / 2];
|
int32 *last_buffer = new int32[sound_buffer_size / 4];
|
||||||
fd_set audio_fdset;
|
fd_set audio_fdset;
|
||||||
int numfds, was_error;
|
int numfds, was_error;
|
||||||
|
|
||||||
@ -257,11 +329,11 @@ static void *stream_func(void *arg)
|
|||||||
sem_wait(&audio_irq_done_sem);
|
sem_wait(&audio_irq_done_sem);
|
||||||
D(bug("stream: ack received\n"));
|
D(bug("stream: ack received\n"));
|
||||||
|
|
||||||
uint32 apple_stream_info; // Mac address of SoundComponentData struct describing next buffer
|
|
||||||
// Get size of audio data
|
// Get size of audio data
|
||||||
apple_stream_info = ReadMacInt32(audio_data + adatStreamInfo);
|
uint32 apple_stream_info = ReadMacInt32(audio_data + adatStreamInfo);
|
||||||
|
if (!current_main_mute &&
|
||||||
if (apple_stream_info) {
|
!current_speaker_mute &&
|
||||||
|
apple_stream_info) {
|
||||||
int work_size = ReadMacInt32(apple_stream_info + scd_sampleCount) * (AudioStatus.sample_size >> 3) * AudioStatus.channels;
|
int work_size = ReadMacInt32(apple_stream_info + scd_sampleCount) * (AudioStatus.sample_size >> 3) * AudioStatus.channels;
|
||||||
D(bug("stream: work_size %d\n", work_size));
|
D(bug("stream: work_size %d\n", work_size));
|
||||||
if (work_size > sound_buffer_size)
|
if (work_size > sound_buffer_size)
|
||||||
@ -269,8 +341,21 @@ static void *stream_func(void *arg)
|
|||||||
if (work_size == 0)
|
if (work_size == 0)
|
||||||
goto silence;
|
goto silence;
|
||||||
|
|
||||||
// Send data to audio library
|
// Send data to audio library. Convert 8-bit data
|
||||||
if (work_size == sound_buffer_size)
|
// unsigned->signed, using same algorithm as audio_amiga.cpp.
|
||||||
|
// It works fine for 8-bit mono, but not stereo.
|
||||||
|
if (AudioStatus.sample_size == 8) {
|
||||||
|
uint32 *p = (uint32 *)Mac2HostAddr(ReadMacInt32(apple_stream_info + scd_buffer));
|
||||||
|
uint32 *q = (uint32 *)last_buffer;
|
||||||
|
int r = work_size >> 2;
|
||||||
|
// XXX not quite right....
|
||||||
|
while (r--)
|
||||||
|
*q++ = *p++ ^ 0x80808080;
|
||||||
|
if (work_size != sound_buffer_size)
|
||||||
|
memset((uint8 *)last_buffer + work_size, silence_byte, sound_buffer_size - work_size);
|
||||||
|
alWriteFrames(port, last_buffer, audio_frames_per_block);
|
||||||
|
}
|
||||||
|
else if (work_size == sound_buffer_size)
|
||||||
alWriteFrames(port, Mac2HostAddr(ReadMacInt32(apple_stream_info + scd_buffer)), audio_frames_per_block);
|
alWriteFrames(port, Mac2HostAddr(ReadMacInt32(apple_stream_info + scd_buffer)), audio_frames_per_block);
|
||||||
else {
|
else {
|
||||||
// Last buffer
|
// Last buffer
|
||||||
@ -313,6 +398,156 @@ static void *stream_func(void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read or set the current output volume using the audio library
|
||||||
|
*/
|
||||||
|
|
||||||
|
static uint32 read_volume(void)
|
||||||
|
{
|
||||||
|
ALpv x[2];
|
||||||
|
ALfixed gain[8];
|
||||||
|
double maxgain, mingain;
|
||||||
|
ALparamInfo pi;
|
||||||
|
uint32 ret = 0x01000100; // default, maximum value
|
||||||
|
int dev = alGetDevice(config);
|
||||||
|
|
||||||
|
// Fetch the maximum and minimum gain settings
|
||||||
|
|
||||||
|
alGetParamInfo(dev, AL_GAIN, &pi);
|
||||||
|
maxgain = alFixedToDouble(pi.max.ll);
|
||||||
|
mingain = alFixedToDouble(pi.min.ll);
|
||||||
|
// printf("maxgain = %lf dB, mingain = %lf dB\n", maxgain, mingain);
|
||||||
|
|
||||||
|
// Get the current gain values
|
||||||
|
|
||||||
|
x[0].param = AL_GAIN;
|
||||||
|
x[0].value.ptr = gain;
|
||||||
|
x[0].sizeIn = sizeof(gain) / sizeof(gain[0]);
|
||||||
|
x[1].param = AL_CHANNELS;
|
||||||
|
if (alGetParams(dev, x, 2) < 0) {
|
||||||
|
printf("alGetParams failed: %s\n", alGetErrorString(oserror()));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (x[0].sizeOut < 0) {
|
||||||
|
printf("AL_GAIN was an unrecognized parameter\n");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
double v;
|
||||||
|
uint32 left, right;
|
||||||
|
|
||||||
|
// Left
|
||||||
|
v = alFixedToDouble(gain[0]);
|
||||||
|
if (v < mingain)
|
||||||
|
v = mingain; // handle gain == -inf
|
||||||
|
v = (v - mingain) / (maxgain - mingain); // scale to 0..1
|
||||||
|
left = (uint32)(v * (double)256); // convert to 8.8 fixed point
|
||||||
|
|
||||||
|
// Right
|
||||||
|
if (x[0].sizeOut <= 1) { // handle a mono interface
|
||||||
|
right = left;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
v = alFixedToDouble(gain[1]);
|
||||||
|
if (v < mingain)
|
||||||
|
v = mingain; // handle gain == -inf
|
||||||
|
v = (v - mingain) / (maxgain - mingain); // scale to 0..1
|
||||||
|
right = (uint32)(v * (double)256); // convert to 8.8 fixed point
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = (left << 16) | right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_volume(uint32 vol)
|
||||||
|
{
|
||||||
|
ALpv x[1];
|
||||||
|
ALfixed gain[2]; // left and right
|
||||||
|
double maxgain, mingain;
|
||||||
|
ALparamInfo pi;
|
||||||
|
int dev = alGetDevice(config);
|
||||||
|
|
||||||
|
// Fetch the maximum and minimum gain settings
|
||||||
|
|
||||||
|
alGetParamInfo(dev, AL_GAIN, &pi);
|
||||||
|
maxgain = alFixedToDouble(pi.max.ll);
|
||||||
|
mingain = alFixedToDouble(pi.min.ll);
|
||||||
|
|
||||||
|
// Set the new gain values
|
||||||
|
|
||||||
|
x[0].param = AL_GAIN;
|
||||||
|
x[0].value.ptr = gain;
|
||||||
|
x[0].sizeIn = sizeof(gain) / sizeof(gain[0]);
|
||||||
|
|
||||||
|
uint32 left = vol >> 16;
|
||||||
|
uint32 right = vol & 0xffff;
|
||||||
|
double lv, rv;
|
||||||
|
|
||||||
|
if (left == 0 && pi.specialVals & AL_NEG_INFINITY_BIT) {
|
||||||
|
lv = AL_NEG_INFINITY;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lv = ((double)left / 256) * (maxgain - mingain) + mingain;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (right == 0 && pi.specialVals & AL_NEG_INFINITY_BIT) {
|
||||||
|
rv = AL_NEG_INFINITY;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rv = ((double)right / 256) * (maxgain - mingain) + mingain;
|
||||||
|
}
|
||||||
|
|
||||||
|
D(bug("set_volume: left=%lf dB, right=%lf dB\n", lv, rv));
|
||||||
|
|
||||||
|
gain[0] = alDoubleToFixed(lv);
|
||||||
|
gain[1] = alDoubleToFixed(rv);
|
||||||
|
|
||||||
|
if (alSetParams(dev, x, 1) < 0) {
|
||||||
|
printf("alSetParams failed: %s\n", alGetErrorString(oserror()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read or set the mute setting using the audio library
|
||||||
|
*/
|
||||||
|
|
||||||
|
static bool read_mute(void)
|
||||||
|
{
|
||||||
|
bool ret;
|
||||||
|
int dev = alGetDevice(config);
|
||||||
|
ALpv x;
|
||||||
|
x.param = AL_MUTE;
|
||||||
|
|
||||||
|
if (alGetParams(dev, &x, 1) < 0) {
|
||||||
|
printf("alSetParams failed: %s\n", alGetErrorString(oserror()));
|
||||||
|
return current_main_mute; // Or just return false?
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = x.value.i;
|
||||||
|
|
||||||
|
D(bug("read_mute: mute=%d\n", ret));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_mute(bool mute)
|
||||||
|
{
|
||||||
|
D(bug("set_mute: mute=%ld\n", mute));
|
||||||
|
|
||||||
|
int dev = alGetDevice(config);
|
||||||
|
ALpv x;
|
||||||
|
x.param = AL_MUTE;
|
||||||
|
x.value.i = mute;
|
||||||
|
|
||||||
|
if (alSetParams(dev, &x, 1) < 0) {
|
||||||
|
printf("alSetParams failed: %s\n", alGetErrorString(oserror()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MacOS audio interrupt, read next data block
|
* MacOS audio interrupt, read next data block
|
||||||
*/
|
*/
|
||||||
@ -339,23 +574,29 @@ void AudioInterrupt(void)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Set sampling parameters
|
* Set sampling parameters
|
||||||
* "index" is an index into the audio_sample_rates[] etc. arrays
|
* "index" is an index into the audio_sample_rates[] etc. vectors
|
||||||
* It is guaranteed that AudioStatus.num_sources == 0
|
* It is guaranteed that AudioStatus.num_sources == 0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool audio_set_sample_rate(int index)
|
bool audio_set_sample_rate(int index)
|
||||||
{
|
{
|
||||||
return true;
|
close_audio();
|
||||||
|
audio_sample_rate_index = index;
|
||||||
|
return open_audio();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool audio_set_sample_size(int index)
|
bool audio_set_sample_size(int index)
|
||||||
{
|
{
|
||||||
return true;
|
close_audio();
|
||||||
|
audio_sample_size_index = index;
|
||||||
|
return open_audio();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool audio_set_channels(int index)
|
bool audio_set_channels(int index)
|
||||||
{
|
{
|
||||||
return true;
|
close_audio();
|
||||||
|
audio_channel_count_index = index;
|
||||||
|
return open_audio();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -367,36 +608,73 @@ bool audio_set_channels(int index)
|
|||||||
|
|
||||||
bool audio_get_main_mute(void)
|
bool audio_get_main_mute(void)
|
||||||
{
|
{
|
||||||
return false;
|
D(bug("audio_get_main_mute: mute=%ld\n", current_main_mute));
|
||||||
|
|
||||||
|
return current_main_mute;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 audio_get_main_volume(void)
|
uint32 audio_get_main_volume(void)
|
||||||
{
|
{
|
||||||
return 0x01000100;
|
uint32 ret = current_main_volume;
|
||||||
|
|
||||||
|
D(bug("audio_get_main_volume: vol=0x%x\n", ret));
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool audio_get_speaker_mute(void)
|
bool audio_get_speaker_mute(void)
|
||||||
{
|
{
|
||||||
return false;
|
D(bug("audio_get_speaker_mute: mute=%ld\n", current_speaker_mute));
|
||||||
|
|
||||||
|
return current_speaker_mute;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 audio_get_speaker_volume(void)
|
uint32 audio_get_speaker_volume(void)
|
||||||
{
|
{
|
||||||
return 0x01000100;
|
uint32 ret = current_speaker_volume;
|
||||||
|
|
||||||
|
D(bug("audio_get_speaker_volume: vol=0x%x\n", ret));
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void audio_set_main_mute(bool mute)
|
void audio_set_main_mute(bool mute)
|
||||||
{
|
{
|
||||||
|
D(bug("audio_set_main_mute: mute=%ld\n", mute));
|
||||||
|
|
||||||
|
if (mute != current_main_mute) {
|
||||||
|
current_main_mute = mute;
|
||||||
|
}
|
||||||
|
|
||||||
|
set_mute(current_main_mute);
|
||||||
}
|
}
|
||||||
|
|
||||||
void audio_set_main_volume(uint32 vol)
|
void audio_set_main_volume(uint32 vol)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
D(bug("audio_set_main_volume: vol=%x\n", vol));
|
||||||
|
|
||||||
|
current_main_volume = vol;
|
||||||
|
|
||||||
|
set_volume(vol);
|
||||||
}
|
}
|
||||||
|
|
||||||
void audio_set_speaker_mute(bool mute)
|
void audio_set_speaker_mute(bool mute)
|
||||||
{
|
{
|
||||||
|
D(bug("audio_set_speaker_mute: mute=%ld\n", mute));
|
||||||
|
|
||||||
|
if (mute != current_speaker_mute) {
|
||||||
|
current_speaker_mute = mute;
|
||||||
|
}
|
||||||
|
|
||||||
|
set_mute(current_speaker_mute);
|
||||||
}
|
}
|
||||||
|
|
||||||
void audio_set_speaker_volume(uint32 vol)
|
void audio_set_speaker_volume(uint32 vol)
|
||||||
{
|
{
|
||||||
|
D(bug("audio_set_speaker_volume: vol=%x\n", vol));
|
||||||
|
|
||||||
|
current_speaker_volume = vol;
|
||||||
|
|
||||||
|
set_volume(vol);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user