PC audio now supports volume and stereo channels.
This commit is contained in:
parent
ce2d13ba0d
commit
2ca7c683dd
4 changed files with 101 additions and 12 deletions
|
@ -32,7 +32,7 @@
|
|||
#include "jPixBuf.h"
|
||||
|
||||
|
||||
#define AUDIO_FORMAT AUDIO_F32
|
||||
#define AUDIO_FORMAT AUDIO_F32 // PocketMod returns floats.
|
||||
#define AUDIO_FREQUENCY 44100
|
||||
#define AUDIO_CHANNELS 2
|
||||
|
||||
|
@ -73,6 +73,7 @@ static SDL_AudioSpec _jlAudioFormat;
|
|||
static SDL_AudioDeviceID _jlAudioDevice;
|
||||
static jbool _jlModPlaying = jfalse;
|
||||
static jlPlatformModT *_jlModCurrent = NULL;
|
||||
static jbyte _jlModVolume = 255;
|
||||
static jlSoundPlayingT *_jlSoundList = NULL;
|
||||
|
||||
|
||||
|
@ -80,6 +81,9 @@ static Uint32 _jlUtilTimer(Uint32 interval, void *param);
|
|||
static void _jlAudioCallback(void *userdata, Uint8 *buffer, int bytes);
|
||||
|
||||
|
||||
extern jbool _jlSwapChannels;
|
||||
|
||||
|
||||
/*
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wcast-align"
|
||||
|
@ -154,11 +158,21 @@ void _jlPutPixel(SDL_Surface *surface, int x, int y, Uint32 pixel) {
|
|||
|
||||
|
||||
static void _jlAudioCallback(void *userdata, Uint8 *buffer, int bytes) {
|
||||
int i = 0;
|
||||
jlSoundPlayingT *sound = NULL;
|
||||
jlSoundPlayingT *prev = NULL;
|
||||
jlSoundPlayingT *temp = NULL;
|
||||
uint32_t length;
|
||||
int i = 0;
|
||||
jlSoundPlayingT *sound = NULL;
|
||||
jlSoundPlayingT *prev = NULL;
|
||||
jlSoundPlayingT *temp = NULL;
|
||||
uint32_t length = 0;
|
||||
float *data = NULL;
|
||||
float *out = NULL;
|
||||
float adjust = 1;
|
||||
double work = 0;
|
||||
uint8_t *mix = NULL;
|
||||
jbool isRight = jfalse;
|
||||
static uint8_t *samples = NULL;
|
||||
static uint32_t sampleBufferSize = 0;
|
||||
|
||||
(void)userdata;
|
||||
|
||||
// Silence buffer.
|
||||
memset(buffer, 0, bytes);
|
||||
|
@ -166,8 +180,25 @@ static void _jlAudioCallback(void *userdata, Uint8 *buffer, int bytes) {
|
|||
// Load in music.
|
||||
if (_jlModPlaying) {
|
||||
while (i < bytes) {
|
||||
//***TODO*** No MOD volume control.
|
||||
i += pocketmod_render(userdata, buffer + i, bytes - i);
|
||||
i += pocketmod_render(&_jlModContext, buffer + i, bytes - i);
|
||||
}
|
||||
// Adjust volume.
|
||||
adjust = ((100.0 / 255.0) * (float)_jlModVolume) * 0.01;
|
||||
data = (float *)buffer;
|
||||
for (i=0; i<(int)(bytes / sizeof(float)); i+=2) {
|
||||
data[i] *= adjust;
|
||||
data[i + 1] *= adjust;
|
||||
}
|
||||
}
|
||||
|
||||
// Create a sample buffer for manipulating sound effects.
|
||||
if (sampleBufferSize < (uint32_t)bytes) {
|
||||
if (samples) jlFree(samples);
|
||||
samples = jlMalloc(bytes);
|
||||
if (samples) {
|
||||
sampleBufferSize = bytes;
|
||||
} else {
|
||||
sampleBufferSize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -175,8 +206,32 @@ static void _jlAudioCallback(void *userdata, Uint8 *buffer, int bytes) {
|
|||
if (_jlSoundList) {
|
||||
sound = _jlSoundList;
|
||||
while (sound) {
|
||||
length = ((uint32_t)bytes > sound->len) ? sound->len : bytes;
|
||||
SDL_MixAudioFormat(buffer, sound->buffer, AUDIO_FORMAT, length, sound->volume * 0.5);
|
||||
length = ((uint32_t)bytes > sound->len) ? sound->len : (uint32_t)bytes;
|
||||
// If we have a sample buffer, move sound to desired channel.
|
||||
if (samples) {
|
||||
mix = samples;
|
||||
out = (float *)samples;
|
||||
data = (float *)sound->buffer;
|
||||
for (i=0; i<(int)(length / sizeof(float)); i+=2) {
|
||||
// Combine channels into a mono sample.
|
||||
work = (data[i] + data[i + 1]) * 0.5;
|
||||
// Determine channel.
|
||||
isRight = (sound->channel & 0x01);
|
||||
if (_jlSwapChannels) isRight = !isRight;
|
||||
if (isRight) {
|
||||
// Move sound into right channel.
|
||||
out[i] = 0;
|
||||
out[i + 1] = work;
|
||||
} else {
|
||||
// Move sound into left channel.
|
||||
out[i] = work;
|
||||
out[i + 1] = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mix = sound->buffer;
|
||||
}
|
||||
SDL_MixAudioFormat(buffer, mix, AUDIO_FORMAT, length, sound->volume * 0.5);
|
||||
sound->buffer += length;
|
||||
sound->len -= length;
|
||||
// Are we done with this sound?
|
||||
|
@ -391,6 +446,11 @@ void jlModStop(void) {
|
|||
}
|
||||
|
||||
|
||||
void jlModVolume(jbyte volume) {
|
||||
_jlModVolume = volume;
|
||||
}
|
||||
|
||||
|
||||
void jlSoundFree(jlSoundT *sound) {
|
||||
jlPlatformSoundT *s = (jlPlatformSoundT *)sound;
|
||||
|
||||
|
@ -662,7 +722,7 @@ int main(int argc, char *argv[]) {
|
|||
_jlAudioFormat.channels = 2;
|
||||
_jlAudioFormat.samples = AUDIO_CHANNELS;
|
||||
_jlAudioFormat.callback = _jlAudioCallback;
|
||||
_jlAudioFormat.userdata = &_jlModContext;
|
||||
_jlAudioFormat.userdata = NULL;
|
||||
_jlAudioDevice = SDL_OpenAudioDevice(NULL, 0, &_jlAudioFormat, &_jlAudioFormat, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE);
|
||||
if (!_jlAudioDevice) jlUtilDie(SDL_GetError());
|
||||
SDL_PauseAudioDevice(_jlAudioDevice, 0);
|
||||
|
|
|
@ -74,6 +74,10 @@ jmp_buf _jlJumpBuffer;
|
|||
jbool _jlIsRunning = jtrue;
|
||||
#endif
|
||||
|
||||
#ifndef JL_HAS_SOUNDSWAPCHANNELS
|
||||
jbool _jlSwapChannels = jfalse;
|
||||
#endif
|
||||
|
||||
|
||||
static jlColorT _jlDefaultPalette[16];
|
||||
static jlStackT *_jlFillStackTop = NULL;
|
||||
|
@ -797,6 +801,13 @@ void jlModStop(void) {
|
|||
#endif
|
||||
|
||||
|
||||
#ifndef JL_HAS_MODVOLUME
|
||||
void jlModVolume(jbyte volume) {
|
||||
(void)volume;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef JL_HAS_PALETTEDEFAULT
|
||||
void jlPaletteDefault(void) {
|
||||
jbyte i;
|
||||
|
@ -882,6 +893,13 @@ void jlSoundStop(jlSoundT *sound) {
|
|||
#endif
|
||||
|
||||
|
||||
#ifndef JL_HAS_SOUNDSWAPCHANNELS
|
||||
void jlSoundSwapChannels(jbool swap) {
|
||||
_jlSwapChannels = swap;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef JL_HAS_STNFREE
|
||||
void jlStnFree(jlStnT *stn) {
|
||||
if (stn != NULL) {
|
||||
|
|
|
@ -98,6 +98,7 @@ typedef unsigned int juint32;
|
|||
#define JL_HAS_MODPAUSE
|
||||
#define JL_HAS_MODPLAY
|
||||
#define JL_HAS_MODSTOP
|
||||
#define JL_HAS_MODVOLUME
|
||||
#define JL_HAS_PALETTESET
|
||||
#define JL_HAS_PALETTESETFROMIMG
|
||||
#define JL_HAS_SOUNDFREE
|
||||
|
@ -142,6 +143,7 @@ typedef unsigned int juint32;
|
|||
#define JL_HAS_MODPAUSE
|
||||
#define JL_HAS_MODPLAY
|
||||
#define JL_HAS_MODSTOP
|
||||
#define JL_HAS_MODVOLUME
|
||||
#define JL_HAS_PALETTESET
|
||||
#define JL_HAS_PALETTESETFROMIMG
|
||||
#define JL_HAS_SOUNDFREE
|
||||
|
@ -186,6 +188,7 @@ typedef unsigned int juint32;
|
|||
#define JL_HAS_MODPAUSE
|
||||
#define JL_HAS_MODPLAY
|
||||
#define JL_HAS_MODSTOP
|
||||
#define JL_HAS_MODVOLUME
|
||||
#define JL_HAS_PALETTESET
|
||||
#define JL_HAS_PALETTESETFROMIMG
|
||||
#define JL_HAS_SOUNDFREE
|
||||
|
@ -440,6 +443,7 @@ jbool _jlModLoad(jlModT **mod, char *filename);
|
|||
void jlModPause(void);
|
||||
void jlModPlay(jlModT *mod);
|
||||
void jlModStop(void);
|
||||
void jlModVolume(jbyte volume);
|
||||
|
||||
void jlPaletteDefault(void); //***TODO*** Treat palettes like we do "surfaces" - allow changing STAs or display
|
||||
void jlPaletteSet(jbyte index, jbyte r, jbyte g, jbyte b); //***TODO*** Really need a matching "get"
|
||||
|
@ -451,6 +455,7 @@ jbool jlSoundIsPlaying(jlSoundT *sound);
|
|||
jbool _jlSoundLoad(jlSoundT **sound, char *filename);
|
||||
void jlSoundPlay(jlSoundT *sound, jlSoundChannelE channel, jbyte volume);
|
||||
void jlSoundStop(jlSoundT *sound);
|
||||
void jlSoundSwapChannels(jbool swap);
|
||||
|
||||
void jlStnFree(jlStnT *stn);
|
||||
#define jlStnLoad(stn, filename) _jlStnLoad((jlStnT **)&(stn), filename, __LINE__, (char *)__FILE__) // Syntatic Sugar
|
||||
|
|
|
@ -290,6 +290,7 @@ void musicTest(void) {
|
|||
jlModT *music = NULL;
|
||||
jlSoundT *sound1 = NULL;
|
||||
jlSoundT *sound2 = NULL;
|
||||
jbyte volume = 0;
|
||||
|
||||
if (!jlImgLoad(kanga, "kanga")) jlUtilDie("Unable to load kanga.img!");
|
||||
if (!jlImgLoad(font, "font")) jlUtilDie("Unable to load font.img!");
|
||||
|
@ -302,12 +303,17 @@ void musicTest(void) {
|
|||
|
||||
jlModPlay(music);
|
||||
|
||||
jlSoundPlay(sound2, CHANNEL_FRONT_RIGHT, 255);
|
||||
//jlSoundSwapChannels(jtrue);
|
||||
jlSoundPlay(sound1, CHANNEL_FRONT_LEFT, 255);
|
||||
jlSoundPlay(sound2, CHANNEL_FRONT_RIGHT, 255);
|
||||
|
||||
while (!jlKeyPressed()) {
|
||||
fontPrint(font, NULL, 1, 1, "%dx%d %d %d ", jlGameGetAxis(0), jlGameGetAxis(1), jlGameGetButton(0), jlGameGetButton(1));
|
||||
jlDisplayPresent();
|
||||
if (volume < 255) {
|
||||
volume++;
|
||||
jlModVolume(volume);
|
||||
}
|
||||
}
|
||||
jlKeyRead();
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue