- supported audio formats are now kept in STL vectors

- added run-time audio parameter switching for OSS/ESD audio output
- setting ESPEAKER env variable causes B2 to try ESD before OSS
This commit is contained in:
cebix 2001-07-05 20:30:54 +00:00
parent abd6539568
commit 7eb6ed2b86
11 changed files with 282 additions and 169 deletions

View File

@ -9,6 +9,8 @@ V1.0 (snapshot) - <date>
depth, which can be switched on-the-fly
- Unix: Ctrl-F5 grabs mouse in windowed mode (enhanced compatibility
with games like flight simulators)
- Unix: audio sample rate, bit depth and channel count are adjustable
in the MacOS "Sound" control panel
V0.9 (release 0.9-1) - 31.May 2001
- final adjustments for 0.9 release

View File

@ -10,7 +10,6 @@ General:
- Disk: rdVerify
- CD-ROM: track lists, positioning type 3, TOC type 4/5, ReadHeader/ReadMCN/
ReadISRC/ReadAudio/ReadAllSubcodes
- Sound output rate/bits/channels switching
- Sound in
- Video: multiple monitor support
- More accurate Time Manager
@ -31,10 +30,12 @@ AmigaOS:
- Patch 512K ROM for 68040/060 caches
- Input handler instead of IDCMP?
- Last sound buffer is not played
- Sound output rate/bits/channels switching
BeOS:
- clip_beos.cpp: clip BeOS->Basilisk
- Last sound buffer is not played
- Sound output rate/bits/channels switching
Unix:
- clip_unix.cpp: clip Unix->Basilisk
@ -42,7 +43,6 @@ Unix:
- sys_unix.cpp: SysFormat(), SysIsFixedDisk(), SysIsDiskInserted(), prevent/allow
for non-floppy/CDROM devices
- scsi_linux.cpp: adapt to SCSI Generic driver V2.0
- ESD vs. /dev/dsp should be a prefs item
- ESD is also available on Solaris
- maybe use SDL for sound?
- serial_unix.cpp: provide a way to pipe input/output to programs

View File

@ -37,15 +37,6 @@
#include "debug.h"
// Supported sample rates, sizes and channels
int audio_num_sample_rates = 1;
uint32 audio_sample_rates[] = {22050 << 16};
int audio_num_sample_sizes = 1;
uint16 audio_sample_sizes[] = {16};
int audio_num_channel_counts = 1;
uint16 audio_channel_counts[] = {2};
// Global variables
static ULONG ahi_id = AHI_DEFAULT_ID; // AHI audio ID
static struct AHIAudioCtrl *ahi_ctrl = NULL;
@ -64,14 +55,23 @@ static __saveds __attribute__((regparm(3))) ULONG audio_callback(struct Hook *ho
* Initialization
*/
// Set AudioStatus to reflect current audio stream format
static void set_audio_status_format(void)
{
AudioStatus.sample_rate = audio_sample_rates[0];
AudioStatus.sample_size = audio_sample_sizes[0];
AudioStatus.channels = audio_channel_counts[0];
}
void AudioInit(void)
{
sample[0].ahisi_Address = sample[1].ahisi_Address = NULL;
// Init audio status and feature flags
AudioStatus.sample_rate = audio_sample_rates[0];
AudioStatus.sample_size = audio_sample_sizes[0];
AudioStatus.channels = audio_channel_counts[0];
audio_sample_rates.push_back(22050 << 16);
audio_sample_sizes.push_back(16);
audio_channel_counts.push_back(2);
set_audio_status_format();
AudioStatus.mixer = 0;
AudioStatus.num_sources = 0;
audio_component_flags = cmpWantsRegisterMessage | kStereoOut | k16BitOut;
@ -250,16 +250,19 @@ void AudioInterrupt(void)
* It is guaranteed that AudioStatus.num_sources == 0
*/
void audio_set_sample_rate(int index)
bool audio_set_sample_rate(int index)
{
return true;
}
void audio_set_sample_size(int index)
bool audio_set_sample_size(int index)
{
return true;
}
void audio_set_channels(int index)
bool audio_set_channels(int index)
{
return true;
}

View File

@ -35,14 +35,6 @@
#include "debug.h"
// Supported sample rates, sizes and channels
int audio_num_sample_rates = 1;
uint32 audio_sample_rates[] = {44100 << 16};
int audio_num_sample_sizes = 1;
uint16 audio_sample_sizes[] = {16};
int audio_num_channel_counts = 1;
uint16 audio_channel_counts[] = {2};
// Global variables
static int audio_irq_done_sem = -1; // Signal from interrupt to streaming thread: data block read
static BSoundPlayer *the_player;
@ -107,12 +99,21 @@ static status_t audio_manager(void *arg)
* Initialization
*/
void AudioInit(void)
// Set AudioStatus to reflect current audio stream format
static void set_audio_status_format(void)
{
// Init audio status and feature flags
AudioStatus.sample_rate = audio_sample_rates[0];
AudioStatus.sample_size = audio_sample_sizes[0];
AudioStatus.channels = audio_channel_counts[0];
}
void AudioInit(void)
{
// Init audio status and feature flags
audio_sample_rates.push_back(44100 << 16);
audio_sample_sizes.push_back(16);
audio_channel_counts.push_back(2);
set_audio_status_format();
AudioStatus.mixer = 0;
AudioStatus.num_sources = 0;
audio_component_flags = cmpWantsRegisterMessage | kStereoOut | k16BitOut;
@ -274,16 +275,19 @@ void AudioInterrupt(void)
* It is guaranteed that AudioStatus.num_sources == 0
*/
void audio_set_sample_rate(int index)
bool audio_set_sample_rate(int index)
{
return true;
}
void audio_set_sample_size(int index)
bool audio_set_sample_size(int index)
{
return true;
}
void audio_set_channels(int index)
bool audio_set_channels(int index)
{
return true;
}

View File

@ -40,14 +40,6 @@
#include "debug.h"
// Supported sample rates, sizes and channels (defaults)
int audio_num_sample_rates = 1;
uint32 audio_sample_rates[] = {44100 << 16};
int audio_num_sample_sizes = 1;
uint16 audio_sample_sizes[] = {16};
int audio_num_channel_counts = 1;
uint16 audio_channel_counts[] = {2};
// Global variables
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
@ -168,6 +160,9 @@ bool audio_init_al(void)
void AudioInit(void)
{
// Init audio status (defaults) and feature flags
audio_sample_rates.push_back(44100 << 16);
audio_sample_sizes.push_back(16);
audio_channel_counts.push_back(2);
set_audio_status_format();
AudioStatus.mixer = 0;
AudioStatus.num_sources = 0;

View File

@ -40,14 +40,6 @@
#include "debug.h"
// Supported sample rates, sizes and channels
int audio_num_sample_rates = 1;
uint32 audio_sample_rates[] = {44100 << 16};
int audio_num_sample_sizes = 1;
uint16 audio_sample_sizes[] = {16};
int audio_num_channel_counts = 1;
uint16 audio_channel_counts[] = {2};
// Global variables
static int fd = -1; // fd of /dev/audio
static sem_t audio_irq_done_sem; // Signal from interrupt to streaming thread: data block read
@ -64,14 +56,23 @@ static void *stream_func(void *arg);
* Initialization
*/
// Set AudioStatus to reflect current audio stream format
static void set_audio_status_format(void)
{
AudioStatus.sample_rate = audio_sample_rates[0];
AudioStatus.sample_size = audio_sample_sizes[0];
AudioStatus.channels = audio_channel_counts[0];
}
void AudioInit(void)
{
char str[256];
// Init audio status and feature flags
AudioStatus.sample_rate = audio_sample_rates[0];
AudioStatus.sample_size = audio_sample_sizes[0];
AudioStatus.channels = audio_channel_counts[0];
audio_sample_rates.push_back(44100 << 16);
audio_sample_sizes.push_back(16);
audio_channel_counts.push_back(2);
set_audio_status_format();
AudioStatus.mixer = 0;
AudioStatus.num_sources = 0;
audio_component_flags = cmpWantsRegisterMessage | kStereoOut | k16BitOut;

View File

@ -49,13 +49,10 @@
#include "debug.h"
// Supported sample rates, sizes and channels (defaults)
int audio_num_sample_rates = 1;
uint32 audio_sample_rates[] = {44100 << 16};
int audio_num_sample_sizes = 1;
uint16 audio_sample_sizes[] = {16};
int audio_num_channel_counts = 1;
uint16 audio_channel_counts[] = {2};
// 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;
// Constants
#define DSP_NAME "/dev/dsp"
@ -63,6 +60,7 @@ uint16 audio_channel_counts[] = {2};
// Global variables
static int audio_fd = -1; // fd of /dev/dsp or ESD
static int mixer_fd = -1; // fd of /dev/mixer
static bool formats_known = false; // Flag: available audio formats have been probed
static sem_t audio_irq_done_sem; // Signal from interrupt to streaming thread: data block read
static bool sem_inited = false; // Flag: audio_irq_done_sem initialized
static int sound_buffer_size; // Size of sound buffer in bytes
@ -84,70 +82,120 @@ static void *stream_func(void *arg);
// Set AudioStatus to reflect current audio stream format
static void set_audio_status_format(void)
{
AudioStatus.sample_rate = audio_sample_rates[0];
AudioStatus.sample_size = audio_sample_sizes[0];
AudioStatus.channels = audio_channel_counts[0];
AudioStatus.sample_rate = audio_sample_rates[audio_sample_rate_index];
AudioStatus.sample_size = audio_sample_sizes[audio_sample_size_index];
AudioStatus.channels = audio_channel_counts[audio_channel_count_index];
}
// Init using /dev/dsp, returns false on error
bool audio_init_dsp(void)
static bool open_dsp(void)
{
// Open /dev/dsp
audio_fd = open(DSP_NAME, O_WRONLY);
if (audio_fd < 0) {
fprintf(stderr, "WARNING: Cannot open %s (%s)\n", DSP_NAME, strerror(errno));
return false;
}
printf("Using " DSP_NAME " audio output\n");
// Get supported sample formats
unsigned long format;
ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &format);
if ((format & (AFMT_U8 | AFMT_S16_BE | AFMT_S16_LE)) == 0) {
WarningAlert(GetString(STR_AUDIO_FORMAT_WARN));
close(audio_fd);
audio_fd = -1;
return false;
if (!formats_known) {
unsigned long format;
ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &format);
if (format & AFMT_U8)
audio_sample_sizes.push_back(8);
if (format & (AFMT_S16_BE | AFMT_S16_LE))
audio_sample_sizes.push_back(16);
int stereo = 0;
if (ioctl(audio_fd, SNDCTL_DSP_STEREO, &stereo) == 0 && stereo == 0)
audio_channel_counts.push_back(1);
stereo = 1;
if (ioctl(audio_fd, SNDCTL_DSP_STEREO, &stereo) == 0 && stereo == 1)
audio_channel_counts.push_back(2);
if (audio_sample_sizes.empty() || audio_channel_counts.empty()) {
WarningAlert(GetString(STR_AUDIO_FORMAT_WARN));
close(audio_fd);
audio_fd = -1;
return false;
}
audio_sample_rates.push_back(11025 << 16);
audio_sample_rates.push_back(22050 << 16);
int rate = 44100;
ioctl(audio_fd, SNDCTL_DSP_SPEED, &rate);
if (rate > 22050)
audio_sample_rates.push_back(rate << 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;
formats_known = true;
}
if (format & (AFMT_S16_BE | AFMT_S16_LE)) {
audio_sample_sizes[0] = 16;
silence_byte = 0;
} else {
audio_sample_sizes[0] = 8;
silence_byte = 0x80;
}
if (!(format & AFMT_S16_BE))
little_endian = true;
// Set DSP parameters
format = audio_sample_sizes[0] == 8 ? AFMT_U8 : (little_endian ? AFMT_S16_LE : AFMT_S16_BE);
unsigned long format;
if (audio_sample_sizes[audio_sample_size_index] == 8) {
format = AFMT_U8;
little_endian = false;
silence_byte = 0x80;
} else {
unsigned long sup_format;
ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &format);
if (sup_format & AFMT_S16_BE) {
little_endian = false;
format = AFMT_S16_BE;
} else {
little_endian = true;
format = AFMT_S16_LE;
}
silence_byte = 0;
}
ioctl(audio_fd, SNDCTL_DSP_SETFMT, &format);
int frag = 0x0004000c; // Block size: 4096 frames
ioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &frag);
int stereo = (audio_channel_counts[0] == 2);
int stereo = (audio_channel_counts[audio_channel_count_index] == 2);
ioctl(audio_fd, SNDCTL_DSP_STEREO, &stereo);
int rate = audio_sample_rates[0] >> 16;
int rate = audio_sample_rates[audio_sample_rate_index] >> 16;
ioctl(audio_fd, SNDCTL_DSP_SPEED, &rate);
audio_sample_rates[0] = rate << 16;
// Set AudioStatus again because we now know more about the sound
// system's capabilities
set_audio_status_format();
// Get sound buffer size
ioctl(audio_fd, SNDCTL_DSP_GETBLKSIZE, &audio_frames_per_block);
D(bug("DSP_GETBLKSIZE %d\n", audio_frames_per_block));
sound_buffer_size = (AudioStatus.sample_size >> 3) * AudioStatus.channels * audio_frames_per_block;
return true;
}
// Init using ESD, returns false on error
bool audio_init_esd(void)
static bool open_esd(void)
{
#ifdef ENABLE_ESD
printf("Using ESD audio output\n");
// ESD supports a variety of audio formats
if (!formats_known) {
audio_sample_rates.push_back(11025 << 16);
audio_sample_rates.push_back(22050 << 16);
audio_sample_rates.push_back(44100 << 16);
audio_sample_sizes.push_back(8);
audio_sample_sizes.push_back(16);
audio_channel_counts.push_back(1);
audio_channel_counts.push_back(2);
// Default to 44.1kHz, 16-bit, stereo
audio_sample_rate_index = 2;
audio_sample_size_index = 1;
audio_channel_count_index = 1;
formats_known = true;
}
// ESD audio format
esd_format_t format = ESD_STREAM | ESD_PLAY;
if (AudioStatus.sample_size == 8)
if (audio_sample_sizes[audio_sample_size_index] == 8)
format |= ESD_BITS8;
else
format |= ESD_BITS16;
if (AudioStatus.channels == 1)
if (audio_channel_counts[audio_channel_count_index] == 1)
format |= ESD_MONO;
else
format |= ESD_STEREO;
@ -160,62 +208,49 @@ bool audio_init_esd(void)
silence_byte = 0; // Is this correct for 8-bit mode?
// Open connection to ESD server
audio_fd = esd_play_stream(format, AudioStatus.sample_rate >> 16, NULL, NULL);
audio_fd = esd_play_stream(format, audio_sample_rates[audio_sample_rate_index] >> 16, NULL, NULL);
if (audio_fd < 0) {
char str[256];
sprintf(str, GetString(STR_NO_ESD_WARN), strerror(errno));
WarningAlert(str);
fprintf(stderr, "WARNING: Cannot open ESD connection\n");
formats_known = false;
return false;
}
printf("Using ESD audio output\n");
// Sound buffer size = 4096 frames
audio_frames_per_block = 4096;
sound_buffer_size = (AudioStatus.sample_size >> 3) * AudioStatus.channels * audio_frames_per_block;
return true;
#else
ErrorAlert("Basilisk II has been compiled with ESD support disabled.");
return false;
#endif
}
void AudioInit(void)
static bool open_audio(void)
{
char str[256];
// Init audio status (defaults) and feature flags
set_audio_status_format();
AudioStatus.mixer = 0;
AudioStatus.num_sources = 0;
audio_component_flags = cmpWantsRegisterMessage | kStereoOut | k16BitOut;
// Sound disabled in prefs? Then do nothing
if (PrefsFindBool("nosound"))
return;
#ifdef ENABLE_ESD
// If ESPEAKER is set, the user probably wants to use ESD, so try that first
if (getenv("ESPEAKER"))
if (open_esd())
goto dev_opened;
#endif
// Try to open /dev/dsp
audio_fd = open(DSP_NAME, O_WRONLY);
if (audio_fd < 0) {
if (open_dsp())
goto dev_opened;
#ifdef ENABLE_ESD
if (!audio_init_esd())
return;
#else
sprintf(str, GetString(STR_NO_AUDIO_DEV_WARN), DSP_NAME, strerror(errno));
WarningAlert(str);
return;
// Hm, /dev/dsp failed so we try ESD again if ESPEAKER wasn't set
if (!getenv("ESPEAKER"))
if (open_esd())
goto dev_opened;
#endif
} else
if (!audio_init_dsp())
return;
// Try to open /dev/mixer
mixer_fd = open("/dev/mixer", O_RDWR);
if (mixer_fd < 0)
printf("WARNING: Cannot open /dev/mixer (%s)", strerror(errno));
// No audio device succeeded
WarningAlert(GetString(STR_NO_AUDIO_WARN));
return false;
// Init semaphore
if (sem_init(&audio_irq_done_sem, 0, 0) < 0)
return;
sem_inited = true;
// Device opened, set AudioStatus
dev_opened:
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();
// Start streaming thread
pthread_attr_init(&stream_thread_attr);
@ -228,10 +263,42 @@ void AudioInit(void)
pthread_attr_setschedparam(&stream_thread_attr, &fifo_param);
}
#endif
stream_thread_cancel = false;
stream_thread_active = (pthread_create(&stream_thread, &stream_thread_attr, stream_func, NULL) == 0);
// Everything OK
// Everything went fine
audio_open = true;
return true;
}
void AudioInit(void)
{
char str[256];
// Init audio status (reasonable defaults) and feature flags
AudioStatus.sample_rate = 44100 << 16;
AudioStatus.sample_size = 16;
AudioStatus.channels = 2;
AudioStatus.mixer = 0;
AudioStatus.num_sources = 0;
audio_component_flags = cmpWantsRegisterMessage | kStereoOut | k16BitOut;
// Sound disabled in prefs? Then do nothing
if (PrefsFindBool("nosound"))
return;
// Init semaphore
if (sem_init(&audio_irq_done_sem, 0, 0) < 0)
return;
sem_inited = true;
// Try to open /dev/mixer
mixer_fd = open("/dev/mixer", O_RDWR);
if (mixer_fd < 0)
printf("WARNING: Cannot open /dev/mixer (%s)", strerror(errno));
// Open and initialize audio device
open_audio();
}
@ -239,7 +306,7 @@ void AudioInit(void)
* Deinitialization
*/
void AudioExit(void)
static void close_audio(void)
{
// Stop stream and delete semaphore
if (stream_thread_active) {
@ -250,16 +317,28 @@ void AudioExit(void)
pthread_join(stream_thread, NULL);
stream_thread_active = false;
}
if (sem_inited)
sem_destroy(&audio_irq_done_sem);
// Close /dev/dsp
if (audio_fd > 0)
// Close /dev/dsp or ESD socket
if (audio_fd >= 0) {
close(audio_fd);
audio_fd = -1;
}
audio_open = false;
}
void AudioExit(void)
{
if (sem_inited) {
sem_destroy(&audio_irq_done_sem);
sem_inited = false;
}
// Close /dev/mixer
if (mixer_fd > 0)
if (mixer_fd >= 0) {
close(mixer_fd);
mixer_fd = -1;
}
}
@ -372,20 +451,29 @@ void AudioInterrupt(void)
/*
* 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
*/
void audio_set_sample_rate(int index)
bool audio_set_sample_rate(int index)
{
close_audio();
audio_sample_rate_index = index;
return open_audio();
}
void audio_set_sample_size(int index)
bool audio_set_sample_size(int index)
{
close_audio();
audio_sample_size_index = index;
return open_audio();
}
void audio_set_channels(int index)
bool audio_set_channels(int index)
{
close_audio();
audio_channel_count_index = index;
return open_audio();
}

View File

@ -51,8 +51,8 @@ user_string_def platform_strings[] = {
{STR_SCSI_DEVICE_OPEN_WARN, "Cannot open %s (%s). SCSI Manager access to this device will be disabled."},
{STR_SCSI_DEVICE_NOT_SCSI_WARN, "%s doesn't seem to comply to the Generic SCSI API. SCSI Manager access to this device will be disabled."},
{STR_NO_AUDIO_DEV_WARN, "Cannot open %s (%s). Audio output will be disabled."},
{STR_NO_ESD_WARN, "Cannot open ESD connection. Audio output will be disabled."},
{STR_AUDIO_FORMAT_WARN, "Audio hardware doesn't support signed 16 bit format. Audio output will be disabled."},
{STR_NO_AUDIO_WARN, "No audio device found, audio output will be disabled."},
{STR_AUDIO_FORMAT_WARN, "Audio hardware doesn't seem to support necessary format. Audio output will be disabled."},
{STR_KEYCODE_FILE_WARN, "Cannot open keycode translation file %s (%s)."},
{STR_KEYCODE_VENDOR_WARN, "Cannot find vendor '%s' in keycode translation file %s."},

View File

@ -42,7 +42,7 @@ enum {
STR_SCSI_DEVICE_OPEN_WARN,
STR_SCSI_DEVICE_NOT_SCSI_WARN,
STR_NO_AUDIO_DEV_WARN,
STR_NO_ESD_WARN,
STR_NO_AUDIO_WARN,
STR_AUDIO_FORMAT_WARN,
STR_KEYCODE_FILE_WARN,
STR_KEYCODE_VENDOR_WARN,

View File

@ -36,6 +36,11 @@
#include "debug.h"
// Supported sample rates, sizes and channels
vector<uint32> audio_sample_rates;
vector<uint16> audio_sample_sizes;
vector<uint16> audio_channel_counts;
// Global variables
struct audio_status AudioStatus; // Current audio status (sample rate etc.)
bool audio_open = false; // Flag: audio is initialized and ready
@ -73,15 +78,15 @@ static int32 AudioGetInfo(uint32 infoPtr, uint32 selector, uint32 sourceID)
break;
case siSampleSizeAvailable: {
r.d[0] = audio_num_sample_sizes * 2;
r.d[0] = audio_sample_sizes.size() * 2;
Execute68kTrap(0xa122, &r); // NewHandle()
uint32 h = r.a[0];
if (h == 0)
return memFullErr;
WriteMacInt16(infoPtr + sil_count, audio_num_sample_sizes);
WriteMacInt16(infoPtr + sil_count, audio_sample_sizes.size());
WriteMacInt32(infoPtr + sil_infoHandle, h);
uint32 sp = ReadMacInt32(h);
for (i=0; i<audio_num_sample_sizes; i++)
for (i=0; i<audio_sample_sizes.size(); i++)
WriteMacInt16(sp + i*2, audio_sample_sizes[i]);
break;
}
@ -91,15 +96,15 @@ static int32 AudioGetInfo(uint32 infoPtr, uint32 selector, uint32 sourceID)
break;
case siChannelAvailable: {
r.d[0] = audio_num_channel_counts * 2;
r.d[0] = audio_channel_counts.size() * 2;
Execute68kTrap(0xa122, &r); // NewHandle()
uint32 h = r.a[0];
if (h == 0)
return memFullErr;
WriteMacInt16(infoPtr + sil_count, audio_num_channel_counts);
WriteMacInt16(infoPtr + sil_count, audio_channel_counts.size());
WriteMacInt32(infoPtr + sil_infoHandle, h);
uint32 sp = ReadMacInt32(h);
for (i=0; i<audio_num_channel_counts; i++)
for (i=0; i<audio_channel_counts.size(); i++)
WriteMacInt16(sp + i*2, audio_channel_counts[i]);
break;
}
@ -109,15 +114,15 @@ static int32 AudioGetInfo(uint32 infoPtr, uint32 selector, uint32 sourceID)
break;
case siSampleRateAvailable: {
r.d[0] = audio_num_sample_rates * 4;
r.d[0] = audio_sample_rates.size() * 4;
Execute68kTrap(0xa122, &r); // NewHandle()
uint32 h = r.a[0];
if (h == 0)
return memFullErr;
WriteMacInt16(infoPtr + sil_count, audio_num_sample_rates);
WriteMacInt16(infoPtr + sil_count, audio_sample_rates.size());
WriteMacInt32(infoPtr + sil_infoHandle, h);
uint32 lp = ReadMacInt32(h);
for (i=0; i<audio_num_sample_rates; i++)
for (i=0; i<audio_sample_rates.size(); i++)
WriteMacInt32(lp + i*4, audio_sample_rates[i]);
break;
}
@ -189,10 +194,14 @@ static int32 AudioSetInfo(uint32 infoPtr, uint32 selector, uint32 sourceID)
D(bug(" set sample size %08lx\n", infoPtr));
if (AudioStatus.num_sources)
return siDeviceBusyErr;
for (i=0; i<audio_num_sample_sizes; i++)
if (infoPtr == AudioStatus.sample_size)
return noErr;
for (i=0; i<audio_sample_sizes.size(); i++)
if (audio_sample_sizes[i] == infoPtr) {
audio_set_sample_size(i);
return noErr;
if (audio_set_sample_size(i))
return noErr;
else
return siInvalidSampleSize;
}
return siInvalidSampleSize;
@ -200,10 +209,14 @@ static int32 AudioSetInfo(uint32 infoPtr, uint32 selector, uint32 sourceID)
D(bug(" set sample rate %08lx\n", infoPtr));
if (AudioStatus.num_sources)
return siDeviceBusyErr;
for (i=0; i<audio_num_sample_rates; i++)
if (infoPtr == AudioStatus.sample_rate)
return noErr;
for (i=0; i<audio_sample_rates.size(); i++)
if (audio_sample_rates[i] == infoPtr) {
audio_set_sample_rate(i);
return noErr;
if (audio_set_sample_rate(i))
return noErr;
else
return siInvalidSampleRate;
}
return siInvalidSampleRate;
@ -211,10 +224,14 @@ static int32 AudioSetInfo(uint32 infoPtr, uint32 selector, uint32 sourceID)
D(bug(" set number of channels %08lx\n", infoPtr));
if (AudioStatus.num_sources)
return siDeviceBusyErr;
for (i=0; i<audio_num_channel_counts; i++)
if (infoPtr == AudioStatus.channels)
return noErr;
for (i=0; i<audio_channel_counts.size(); i++)
if (audio_channel_counts[i] == infoPtr) {
audio_set_channels(i);
return noErr;
if (audio_set_channels(i))
return noErr;
else
return badChannel;
}
return badChannel;

View File

@ -21,6 +21,12 @@
#ifndef AUDIO_H
#define AUDIO_H
#include <vector>
#ifndef NO_STD_NAMESPACE
using std::vector;
#endif
extern int32 AudioDispatch(uint32 params, uint32 ti);
extern bool AudioAvailable; // Flag: audio output available (from the software point of view)
@ -41,9 +47,9 @@ extern void AudioInterrupt(void);
extern void audio_enter_stream(void);
extern void audio_exit_stream(void);
extern void audio_set_sample_rate(int index);
extern void audio_set_sample_size(int index);
extern void audio_set_channels(int index);
extern bool audio_set_sample_rate(int index);
extern bool audio_set_sample_size(int index);
extern bool audio_set_channels(int index);
extern bool audio_get_main_mute(void);
extern uint32 audio_get_main_volume(void);
@ -68,12 +74,9 @@ extern bool audio_open; // Flag: audio is open and ready
extern int audio_frames_per_block; // Number of audio frames per block
extern uint32 audio_component_flags; // Component feature flags
extern int audio_num_sample_rates; // Number of supported sample rates
extern uint32 audio_sample_rates[]; // Array of supported sample rates (16.16 fixed point)
extern int audio_num_sample_sizes; // Number of supported sample sizes
extern uint16 audio_sample_sizes[]; // Array of supported sample sizes
extern int audio_num_channel_counts; // Number of supported channel counts
extern uint16 audio_channel_counts[]; // Array of supported channels counts
extern vector<uint32> audio_sample_rates; // Vector of supported sample rates (16.16 fixed point)
extern vector<uint16> audio_sample_sizes; // Vector of supported sample sizes
extern vector<uint16> audio_channel_counts; // Array of supported channels counts
// Audio component global data and 68k routines
enum {