newoswan/seal-hack/src/bedrv.cpp
2019-09-01 21:47:54 +01:00

175 lines
4.7 KiB
C++

/*
* $Id: bedrv.c 0.1 1998/12/19 18:24:26 chasan Exp $
*
* Intel BeOS Release 4 audio driver using the New Media Kit.
*
* Copyright (C) 1998 Carlos Hasan. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <MediaDefs.h>
#include <SoundPlayer.h>
#include "audio.h"
#include "drivers.h"
/*
* BeOS driver configuration structure
*/
static struct {
BSoundPlayer *Player;
LPFNAUDIOWAVE lpfnAudioWave;
} Audio;
/*
* BeOS driver API interface
*/
static UINT AIAPI GetAudioCaps(LPAUDIOCAPS lpCaps)
{
static AUDIOCAPS Caps =
{
AUDIO_PRODUCT_BEOS, "BeOS Sound Player",
AUDIO_FORMAT_1M08 | AUDIO_FORMAT_1S08 |
AUDIO_FORMAT_1M16 | AUDIO_FORMAT_1S16 |
AUDIO_FORMAT_2M08 | AUDIO_FORMAT_2S08 |
AUDIO_FORMAT_2M16 | AUDIO_FORMAT_2S16 |
AUDIO_FORMAT_4M08 | AUDIO_FORMAT_4S08 |
AUDIO_FORMAT_4M16 | AUDIO_FORMAT_4S16
};
memcpy(lpCaps, &Caps, sizeof(AUDIOCAPS));
return AUDIO_ERROR_NONE;
}
static void PlayAudio(void *cookie, void *buffer, size_t size,
const media_raw_audio_format& fmt)
{
static float hitable[256], lotable[256];
static float scale = 0.0f;
float *float_buffer = (float *) buffer;
short *short_buffer = (short *) buffer + (size >> 2);
size >>= 2;
/* lazily build the integer to float translation table */
if (scale == 0.0f) {
int i;
scale = 1.0f / 32768.0f;
for (i = -128; i < 128; i++)
hitable[i & 255] = scale * 256.0f * i;
for (i = 0; i < 255; i++)
lotable[i] = scale * i;
}
/* streams of 44100 Hz, stereo, 32bit floats are supported */
if (fmt.format != media_raw_audio_format::B_AUDIO_FLOAT ||
fmt.channel_count != 2 || fmt.frame_rate != 44100 ||
Audio.lpfnAudioWave == NULL) {
memset(buffer, 0, size);
}
else {
/* make 44100 Hz, stereo, 16-bit signed integer samples */
Audio.lpfnAudioWave((LPBYTE) short_buffer, size << 1);
/* convert to 32-bit float samples using lookup table */
while (size >= 8) {
int *sample = (int *) short_buffer;
int s;
/* TODO: channels will be swapped in big-endian machines */
s = sample[0];
float_buffer[0] = hitable[(s >> 8) & 255] + lotable[s & 255];
float_buffer[1] = hitable[(s >> 24) & 255] + lotable[(s >> 16)&255];
s = sample[1];
float_buffer[2] = hitable[(s >> 8) & 255] + lotable[s & 255];
float_buffer[3] = hitable[(s >> 24) & 255] + lotable[(s >> 16)&255];
s = sample[2];
float_buffer[4] = hitable[(s >> 8) & 255] + lotable[s & 255];
float_buffer[5] = hitable[(s >> 24) & 255] + lotable[(s >> 16)&255];
s = sample[3];
float_buffer[6] = hitable[(s >> 8) & 255] + lotable[s & 255];
float_buffer[7] = hitable[(s >> 24) & 255] + lotable[(s >> 16)&255];
short_buffer += 8;
float_buffer += 8;
size -= 8;
}
while (size-- > 0) {
short s = *short_buffer++;
*float_buffer++ = hitable[(s >> 8) & 255] + lotable[s & 255];
}
}
}
static UINT AIAPI PingAudio(VOID)
{
return AUDIO_ERROR_NONE;
}
static UINT AIAPI OpenAudio(LPAUDIOINFO lpInfo)
{
/* clean up local state structure */
memset(&Audio, 0, sizeof(Audio));
/* create sound player */
if ((Audio.Player = new BSoundPlayer("SEAL Player", PlayAudio)) == NULL)
return AUDIO_ERROR_NODEVICE;
/* force default settings */
lpInfo->nSampleRate = 44100;
lpInfo->wFormat = AUDIO_FORMAT_16BITS | AUDIO_FORMAT_STEREO;
/* start sound player */
Audio.Player->SetHasData(true);
Audio.Player->Start();
return AUDIO_ERROR_NONE;
}
static UINT AIAPI CloseAudio(VOID)
{
if (Audio.Player != NULL) {
/* stop sound player */
Audio.Player->Stop();
/* release sound player */
delete Audio.Player;
Audio.Player = NULL;
}
return AUDIO_ERROR_NONE;
}
static UINT AIAPI UpdateAudio(UINT nFrames)
{
return AUDIO_ERROR_NONE;
}
static UINT AIAPI SetAudioCallback(LPFNAUDIOWAVE lpfnAudioWave)
{
/* set up audio device user's callback function */
Audio.lpfnAudioWave = lpfnAudioWave;
return AUDIO_ERROR_NONE;
}
/*
* BeOS driver public interface
*/
AUDIOWAVEDRIVER BeOSWaveDriver =
{
GetAudioCaps, PingAudio, OpenAudio, CloseAudio,
UpdateAudio, SetAudioCallback
};
AUDIODRIVER BeOSDriver =
{
&BeOSWaveDriver, NULL
};