Show bsndapi.cpp syntax highlighted
/* ______ ___ ___
* /\ _ \ /\_ \ /\_ \
* \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
* \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
* \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
* \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
* \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
* /\____/
* \_/__/
*
* BeOS sound driver implementation.
*
* Originally by Peter Wang, rewritten to use the BSoundPlayer
* class by Angelo Mottola.
*
* See readme.txt for copyright information.
*/
#include "bealleg.h"
#include "allegro/internal/aintern.h"
#include "allegro/platform/aintbeos.h"
#ifndef ALLEGRO_BEOS
#error something is wrong with the makefile
#endif
#ifndef SCAN_DEPEND
#include <media/SoundPlayer.h>
#endif
#ifdef ALLEGRO_BIG_ENDIAN
#define BE_SOUND_ENDIAN B_MEDIA_BIG_ENDIAN
#else
#define BE_SOUND_ENDIAN B_MEDIA_LITTLE_ENDIAN
#endif
sem_id _be_sound_stream_lock = -1;
static bool be_sound_active = false;
static bool be_sound_stream_locked = false;
static BLocker *locker = NULL;
static BSoundPlayer *be_sound = NULL;
static int be_sound_bufsize;
static int be_sound_signed;
static char be_sound_desc[256] = EMPTY_STRING;
/* be_sound_handler:
* Update data.
*/
static void be_sound_handler(void *cookie, void *buffer, size_t size, const media_raw_audio_format &format)
{
locker->Lock();
acquire_sem(_be_sound_stream_lock);
if (be_sound_active) {
be_main_suspend();
_mix_some_samples((unsigned long)buffer, 0, be_sound_signed);
be_main_resume();
}
else {
memset(buffer, 0, size);
}
release_sem(_be_sound_stream_lock);
locker->Unlock();
}
/* be_sound_detect.
* Return TRUE if sound available.
*/
extern "C" int be_sound_detect(int input)
{
BSoundPlayer *sound;
media_raw_audio_format format;
status_t status;
if (input) {
al_ustrzcpy(al_error, AL_ERROR_SIZE, al_get_config_text("Input is not supported"));
return FALSE;
}
format.frame_rate = 11025;
format.channel_count = 1;
format.format = media_raw_audio_format::B_AUDIO_UCHAR;
format.byte_order = BE_SOUND_ENDIAN;
format.buffer_size = 0;
sound = new BSoundPlayer(&format);
status = sound->InitCheck();
delete sound;
return (status == B_OK) ? TRUE : FALSE;
}
/* be_sound_init:
* Init sound driver.
*/
extern "C" int be_sound_init(int input, int voices)
{
media_raw_audio_format format;
char tmp1[128], tmp2[128];
if (input) {
al_ustrzcpy(al_error, AL_ERROR_SIZE, al_get_config_text("Input is not supported"));
return -1;
}
be_sound_active = false;
/* create BPushGameSound instance */
format.frame_rate = (_sound_freq > 0) ? _sound_freq : 44100;
format.channel_count = (_sound_stereo) ? 2 : 1;
format.format = (_sound_bits == 8) ? (media_raw_audio_format::B_AUDIO_UCHAR) : (media_raw_audio_format::B_AUDIO_SHORT);
format.byte_order = BE_SOUND_ENDIAN;
format.buffer_size = 0;
be_sound = new BSoundPlayer(&format, "Sound player", be_sound_handler);
if (be_sound->InitCheck() != B_OK) {
goto cleanup;
}
/* read the sound format back */
format = be_sound->Format();
switch (format.format) {
case media_raw_audio_format::B_AUDIO_UCHAR:
_sound_bits = 8;
be_sound_signed = FALSE;
break;
case media_raw_audio_format::B_AUDIO_SHORT:
_sound_bits = 16;
be_sound_signed = TRUE;
break;
default:
goto cleanup;
}
_sound_stereo = (format.channel_count == 2) ? 1 : 0;
_sound_freq = (int)format.frame_rate;
/* start internal mixer */
be_sound_bufsize = format.buffer_size;
digi_beos.voices = voices;
if (_mixer_init(be_sound_bufsize / (_sound_bits / 8), _sound_freq,
_sound_stereo, ((_sound_bits == 16) ? 1 : 0),
&digi_beos.voices) != 0) {
goto cleanup;
}
/* start audio output */
locker = new BLocker();
if (!locker)
goto cleanup;
be_sound->Start();
be_sound->SetHasData(true);
al_uszprintf(be_sound_desc, sizeof(be_sound_desc), al_get_config_text("%d bits, %s, %d bps, %s"),
_sound_bits, al_uconvert_ascii(be_sound_signed ? "signed" : "unsigned", tmp1),
_sound_freq, al_uconvert_ascii(_sound_stereo ? "stereo" : "mono", tmp2));
digi_driver->desc = be_sound_desc;
be_sound_active = true;
return 0;
cleanup: {
be_sound_exit(input);
return -1;
}
}
/* be_sound_exit:
* Shutdown sound driver.
*/
extern "C" void be_sound_exit(int input)
{
if (input) {
return;
}
be_sound_active = false;
be_sound->Stop();
acquire_sem(_be_sound_stream_lock);
_mixer_exit();
release_sem(_be_sound_stream_lock);
delete be_sound;
delete locker;
be_sound = NULL;
locker = NULL;
}
/* be_sound_lock_voice:
* Locks audio stream for exclusive access.
*/
extern "C" void *be_sound_lock_voice(int voice, int start, int end)
{
if (!be_sound_stream_locked) {
be_sound_stream_locked = true;
acquire_sem(_be_sound_stream_lock);
}
return NULL;
}
/* be_sound_unlock_voice:
* Unlocks audio stream.
*/
void be_sound_unlock_voice(int voice)
{
if (be_sound_stream_locked) {
be_sound_stream_locked = false;
release_sem(_be_sound_stream_lock);
}
}
/* be_sound_buffer_size:
* Returns the current buffer size, for use by the audiostream code.
*/
extern "C" int be_sound_buffer_size()
{
return be_sound_bufsize / (_sound_bits / 8) / (_sound_stereo ? 2 : 1);
}
/* be_sound_mixer_volume:
* Set mixer volume.
*/
extern "C" int be_sound_mixer_volume(int volume)
{
if (!be_sound)
return -1;
be_sound->SetVolume((float)volume / 255.0);
return 0;
}
/* be_sound_suspend:
* Pauses the sound output.
*/
extern "C" void be_sound_suspend(void)
{
if (!be_sound)
return;
locker->Lock();
be_sound_active = false;
locker->Unlock();
}
/* be_sound_resume:
* Resumes the sound output.
*/
extern "C" void be_sound_resume(void)
{
if (!be_sound)
return;
locker->Lock();
be_sound_active = true;
locker->Unlock();
}
See more files for this project here