First shot at new audio data types (int32 and float32).
Notable changes: - Converters between types are autogenerated. Instead of making multiple passes over the data with seperate filters for endianess, size, signedness, etc, converting between data types is always one specialized filter. This simplifies SDL_BuildAudioCVT(), which otherwise had a million edge cases with the new types, and makes the actually conversions more CPU cache friendly. Left a stub for adding specific optimized versions of these routines (SSE/MMX/Altivec, assembler, etc) - Autogenerated converters are built by SDL/src/audio/sdlgenaudiocvt.pl. This does not need to be run unless tweaking the code, and thus doesn't need integration into the build system. - Went through all the drivers and tried to weed out all the "Uint16" references that are better specified with the new SDL_AudioFormat typedef. - Cleaned out a bunch of hardcoded bitwise magic numbers and replaced them with new SDL_AUDIO_* macros. - Added initial float32 and int32 support code. Theoretically, existing drivers will push these through converters to get the data they want to feed to the hardware. Still TODO: - Optimize and debug new converters. - Update the CoreAudio backend to accept float32 data directly. - Other backends, too? - SDL_LoadWAV() needs to be updated to support int32 and float32 .wav files (both of which exist and can be generated by 'sox' for testing purposes). - Update the mixer to handle new datatypes. - Optionally update SDL_sound and SDL_mixer, etc. --HG-- extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%402029
This commit is contained in:
parent
03794d9be1
commit
c500e6c0b4
16 changed files with 3474 additions and 702 deletions
|
@ -286,10 +286,10 @@ SDL_UnlockAudio_Default(SDL_AudioDevice * audio)
|
|||
SDL_mutexV(audio->mixer_lock);
|
||||
}
|
||||
|
||||
static Uint16
|
||||
static SDL_AudioFormat
|
||||
SDL_ParseAudioFormat(const char *string)
|
||||
{
|
||||
Uint16 format = 0;
|
||||
SDL_AudioFormat format = 0;
|
||||
|
||||
switch (*string) {
|
||||
case 'U':
|
||||
|
@ -740,26 +740,34 @@ SDL_AudioQuit(void)
|
|||
}
|
||||
}
|
||||
|
||||
#define NUM_FORMATS 6
|
||||
#define NUM_FORMATS 10
|
||||
static int format_idx;
|
||||
static int format_idx_sub;
|
||||
static Uint16 format_list[NUM_FORMATS][NUM_FORMATS] = {
|
||||
static SDL_AudioFormat format_list[NUM_FORMATS][NUM_FORMATS] = {
|
||||
{AUDIO_U8, AUDIO_S8, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB,
|
||||
AUDIO_U16MSB},
|
||||
AUDIO_U16MSB, AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB},
|
||||
{AUDIO_S8, AUDIO_U8, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB,
|
||||
AUDIO_U16MSB},
|
||||
{AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_U8,
|
||||
AUDIO_S8},
|
||||
{AUDIO_S16MSB, AUDIO_S16LSB, AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_U8,
|
||||
AUDIO_S8},
|
||||
{AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U8,
|
||||
AUDIO_S8},
|
||||
{AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_S16MSB, AUDIO_S16LSB, AUDIO_U8,
|
||||
AUDIO_S8},
|
||||
AUDIO_U16MSB, AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB},
|
||||
{AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_S32LSB,
|
||||
AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_U8, AUDIO_S8},
|
||||
{AUDIO_S16MSB, AUDIO_S16LSB, AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_S32MSB,
|
||||
AUDIO_S32LSB, AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_U8, AUDIO_S8},
|
||||
{AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_S32LSB,
|
||||
AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_U8, AUDIO_S8},
|
||||
{AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_S16MSB, AUDIO_S16LSB, AUDIO_S32MSB,
|
||||
AUDIO_S32LSB, AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_U8, AUDIO_S8},
|
||||
{AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_S16LSB,
|
||||
AUDIO_S16MSB, AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_U8, AUDIO_S8},
|
||||
{AUDIO_S32MSB, AUDIO_S32LSB, AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_S16MSB,
|
||||
AUDIO_S16LSB, AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_U8, AUDIO_S8},
|
||||
{AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_U16LSB,
|
||||
AUDIO_U16MSB, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U8, AUDIO_S8},
|
||||
{AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_S32MSB, AUDIO_S32LSB, AUDIO_U16MSB,
|
||||
AUDIO_U16LSB, AUDIO_S16MSB, AUDIO_S16LSB, AUDIO_U8, AUDIO_S8},
|
||||
};
|
||||
|
||||
Uint16
|
||||
SDL_FirstAudioFormat(Uint16 format)
|
||||
SDL_AudioFormat
|
||||
SDL_FirstAudioFormat(SDL_AudioFormat format)
|
||||
{
|
||||
for (format_idx = 0; format_idx < NUM_FORMATS; ++format_idx) {
|
||||
if (format_list[format_idx][0] == format) {
|
||||
|
@ -770,7 +778,7 @@ SDL_FirstAudioFormat(Uint16 format)
|
|||
return (SDL_NextAudioFormat());
|
||||
}
|
||||
|
||||
Uint16
|
||||
SDL_AudioFormat
|
||||
SDL_NextAudioFormat(void)
|
||||
{
|
||||
if ((format_idx == NUM_FORMATS) || (format_idx_sub == NUM_FORMATS)) {
|
||||
|
|
|
@ -24,12 +24,22 @@
|
|||
/* Functions and variables exported from SDL_audio.c for SDL_sysaudio.c */
|
||||
|
||||
/* Functions to get a list of "close" audio formats */
|
||||
extern Uint16 SDL_FirstAudioFormat(Uint16 format);
|
||||
extern Uint16 SDL_NextAudioFormat(void);
|
||||
extern SDL_AudioFormat SDL_FirstAudioFormat(SDL_AudioFormat format);
|
||||
extern SDL_AudioFormat SDL_NextAudioFormat(void);
|
||||
|
||||
/* Function to calculate the size and silence for a SDL_AudioSpec */
|
||||
extern void SDL_CalculateAudioSpec(SDL_AudioSpec * spec);
|
||||
|
||||
/* The actual mixing thread function */
|
||||
extern int SDLCALL SDL_RunAudio(void *audiop);
|
||||
|
||||
/* this is used internally to access some autogenerated code. */
|
||||
typedef struct
|
||||
{
|
||||
SDL_AudioFormat src_fmt;
|
||||
SDL_AudioFormat dst_fmt;
|
||||
SDL_AudioFilter filter;
|
||||
} SDL_AudioTypeFilters;
|
||||
extern const SDL_AudioTypeFilters sdl_audio_type_filters[];
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
File diff suppressed because it is too large
Load diff
2356
src/audio/SDL_audiotypecvt.c
Normal file
2356
src/audio/SDL_audiotypecvt.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -92,22 +92,27 @@ static const Uint8 mix8[] = {
|
|||
void
|
||||
SDL_MixAudio(Uint8 * dst, const Uint8 * src, Uint32 len, int volume)
|
||||
{
|
||||
Uint16 format;
|
||||
|
||||
if (volume == 0) {
|
||||
return;
|
||||
}
|
||||
/* Mix the user-level audio format */
|
||||
if (current_audio) {
|
||||
SDL_AudioFormat format;
|
||||
if (current_audio->convert.needed) {
|
||||
format = current_audio->convert.src_format;
|
||||
} else {
|
||||
format = current_audio->spec.format;
|
||||
}
|
||||
} else {
|
||||
/* HACK HACK HACK */
|
||||
format = AUDIO_S16;
|
||||
SDL_MixAudioFormat(dst, src, format, len, volume);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SDL_MixAudioFormat(Uint8 * dst, const Uint8 * src, SDL_AudioFormat format,
|
||||
Uint32 len, int volume)
|
||||
{
|
||||
if (volume == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (format) {
|
||||
|
||||
case AUDIO_U8:
|
||||
|
@ -252,6 +257,134 @@ SDL_MixAudio(Uint8 * dst, const Uint8 * src, Uint32 len, int volume)
|
|||
}
|
||||
break;
|
||||
|
||||
case AUDIO_S32LSB:
|
||||
{
|
||||
const Uint32 *src32 = (Uint32 *) src;
|
||||
Uint32 *dst32 = (Uint32 *) dst;
|
||||
Sint32 src1, src2;
|
||||
Sint64 dst_sample;
|
||||
const Sint64 max_audioval = ((((Sint64)1) << (32 - 1)) - 1);
|
||||
const Sint64 min_audioval = -(((Sint64)1) << (32 - 1));
|
||||
|
||||
len /= 4;
|
||||
while (len--) {
|
||||
src1 = (Sint32) SDL_SwapLE32(*src32);
|
||||
src32++;
|
||||
ADJUST_VOLUME(src1, volume);
|
||||
src2 = (Sint32) SDL_SwapLE32(*dst32);
|
||||
dst_sample = src1 + src2;
|
||||
if (dst_sample > max_audioval) {
|
||||
dst_sample = max_audioval;
|
||||
} else if (dst_sample < min_audioval) {
|
||||
dst_sample = min_audioval;
|
||||
}
|
||||
*(dst32++) = SDL_SwapLE32((Uint32) ((Sint32) dst_sample));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case AUDIO_S32MSB:
|
||||
{
|
||||
const Uint32 *src32 = (Uint32 *) src;
|
||||
Uint32 *dst32 = (Uint32 *) dst;
|
||||
Sint32 src1, src2;
|
||||
Sint64 dst_sample;
|
||||
const Sint64 max_audioval = ((((Sint64)1) << (32 - 1)) - 1);
|
||||
const Sint64 min_audioval = -(((Sint64)1) << (32 - 1));
|
||||
|
||||
len /= 4;
|
||||
while (len--) {
|
||||
src1 = (Sint32) SDL_SwapBE32(*src32);
|
||||
src32++;
|
||||
ADJUST_VOLUME(src1, volume);
|
||||
src2 = (Sint32) SDL_SwapBE32(*dst32);
|
||||
dst_sample = src1 + src2;
|
||||
if (dst_sample > max_audioval) {
|
||||
dst_sample = max_audioval;
|
||||
} else if (dst_sample < min_audioval) {
|
||||
dst_sample = min_audioval;
|
||||
}
|
||||
*(dst32++) = SDL_SwapBE32((Uint32) ((Sint32) dst_sample));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case AUDIO_F32LSB:
|
||||
{
|
||||
const float fmaxvolume = 1.0f / ((float) SDL_MIX_MAXVOLUME);
|
||||
const float fvolume = (float) volume;
|
||||
const float *src32 = (float *) src;
|
||||
float *dst32 = (float *) dst;
|
||||
float src1, src2;
|
||||
double dst_sample;
|
||||
/* !!! FIXME: are these right? */
|
||||
const double max_audioval = 3.40282347e+38F;
|
||||
const double min_audioval = -3.40282347e+38F;
|
||||
|
||||
/* !!! FIXME: this is a little nasty. */
|
||||
union { float f; Uint32 ui32; } cvt;
|
||||
|
||||
len /= 4;
|
||||
while (len--) {
|
||||
cvt.f = *(src32++);
|
||||
cvt.ui32 = SDL_SwapLE32(cvt.ui32);
|
||||
src1 = ((cvt.f * fvolume) * fmaxvolume);
|
||||
|
||||
cvt.f = *dst32;
|
||||
cvt.ui32 = SDL_SwapLE32(cvt.ui32);
|
||||
src2 = cvt.f;
|
||||
|
||||
dst_sample = src1 + src2;
|
||||
if (dst_sample > max_audioval) {
|
||||
dst_sample = max_audioval;
|
||||
} else if (dst_sample < min_audioval) {
|
||||
dst_sample = min_audioval;
|
||||
}
|
||||
cvt.f = ((float) dst_sample);
|
||||
cvt.ui32 = SDL_SwapLE32(cvt.ui32);
|
||||
*(dst32++) = cvt.f;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case AUDIO_F32MSB:
|
||||
{
|
||||
const float fmaxvolume = 1.0f / ((float) SDL_MIX_MAXVOLUME);
|
||||
const float fvolume = (float) volume;
|
||||
const float *src32 = (float *) src;
|
||||
float *dst32 = (float *) dst;
|
||||
float src1, src2;
|
||||
double dst_sample;
|
||||
/* !!! FIXME: are these right? */
|
||||
const double max_audioval = 3.40282347e+38F;
|
||||
const double min_audioval = -3.40282347e+38F;
|
||||
|
||||
/* !!! FIXME: this is a little nasty. */
|
||||
union { float f; Uint32 ui32; } cvt;
|
||||
|
||||
len /= 4;
|
||||
while (len--) {
|
||||
cvt.f = *(src32++);
|
||||
cvt.ui32 = SDL_SwapBE32(cvt.ui32);
|
||||
src1 = ((cvt.f * fvolume) * fmaxvolume);
|
||||
|
||||
cvt.f = *dst32;
|
||||
cvt.ui32 = SDL_SwapBE32(cvt.ui32);
|
||||
src2 = cvt.f;
|
||||
|
||||
dst_sample = src1 + src2;
|
||||
if (dst_sample > max_audioval) {
|
||||
dst_sample = max_audioval;
|
||||
} else if (dst_sample < min_audioval) {
|
||||
dst_sample = min_audioval;
|
||||
}
|
||||
cvt.f = ((float) dst_sample);
|
||||
cvt.ui32 = SDL_SwapBE32(cvt.ui32);
|
||||
*(dst32++) = cvt.f;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default: /* If this happens... FIXME! */
|
||||
SDL_SetError("SDL_MixAudio(): unknown audio format");
|
||||
return;
|
||||
|
|
|
@ -483,7 +483,7 @@ ALSA_OpenAudio(_THIS, SDL_AudioSpec * spec)
|
|||
snd_pcm_sw_params_t *swparams;
|
||||
snd_pcm_format_t format;
|
||||
snd_pcm_uframes_t frames;
|
||||
Uint16 test_format;
|
||||
SDL_AudioFormat test_format;
|
||||
|
||||
/* Open the audio device */
|
||||
/* Name of device should depend on # channels in spec */
|
||||
|
|
|
@ -274,7 +274,7 @@ static int
|
|||
ARTS_OpenAudio(_THIS, SDL_AudioSpec * spec)
|
||||
{
|
||||
int bits, frag_spec;
|
||||
Uint16 test_format, format;
|
||||
SDL_AudioFormat test_format, format;
|
||||
|
||||
/* Reset the timer synchronization flag */
|
||||
frame_ticks = 0.0;
|
||||
|
|
|
@ -331,7 +331,7 @@ static int
|
|||
OBSD_OpenAudio(_THIS, SDL_AudioSpec * spec)
|
||||
{
|
||||
char audiodev[64];
|
||||
Uint16 format;
|
||||
SDL_AudioFormat format;
|
||||
audio_info_t info;
|
||||
|
||||
AUDIO_INITINFO(&info);
|
||||
|
|
|
@ -321,7 +321,7 @@ DMA_OpenAudio(_THIS, SDL_AudioSpec * spec)
|
|||
int format;
|
||||
int stereo;
|
||||
int value;
|
||||
Uint16 test_format;
|
||||
SDL_AudioFormat test_format;
|
||||
struct audio_buf_info info;
|
||||
|
||||
/* Reset the timer synchronization flag */
|
||||
|
|
|
@ -172,7 +172,7 @@ DSP_OpenAudio(_THIS, SDL_AudioSpec * spec)
|
|||
int format;
|
||||
int value;
|
||||
int frag_spec;
|
||||
Uint16 test_format;
|
||||
SDL_AudioFormat test_format;
|
||||
|
||||
/* Open the audio device */
|
||||
audio_fd = SDL_OpenAudioPath(audiodev, sizeof(audiodev), OPEN_FLAGS, 0);
|
||||
|
|
|
@ -237,7 +237,7 @@ NAS_OpenAudio(_THIS, SDL_AudioSpec * spec)
|
|||
{
|
||||
AuElement elms[3];
|
||||
int buffer_size;
|
||||
Uint16 test_format, format;
|
||||
SDL_AudioFormat test_format, format;
|
||||
|
||||
this->hidden->mixbuf = NULL;
|
||||
|
||||
|
|
|
@ -348,7 +348,7 @@ NTO_OpenAudio(_THIS, SDL_AudioSpec * spec)
|
|||
{
|
||||
int rval;
|
||||
int format;
|
||||
Uint16 test_format;
|
||||
SDL_AudioFormat test_format;
|
||||
int found;
|
||||
|
||||
audio_handle = NULL;
|
||||
|
|
|
@ -244,7 +244,7 @@ Paud_OpenAudio(_THIS, SDL_AudioSpec * spec)
|
|||
char audiodev[1024];
|
||||
int format;
|
||||
int bytes_per_sample;
|
||||
Uint16 test_format;
|
||||
SDL_AudioFormat test_format;
|
||||
audio_init paud_init;
|
||||
audio_buffer paud_bufinfo;
|
||||
audio_status paud_status;
|
||||
|
|
313
src/audio/sdlgenaudiocvt.pl
Executable file
313
src/audio/sdlgenaudiocvt.pl
Executable file
|
@ -0,0 +1,313 @@
|
|||
#!/usr/bin/perl -w
|
||||
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
my @audiotypes = qw(
|
||||
U8
|
||||
S8
|
||||
U16LSB
|
||||
S16LSB
|
||||
U16MSB
|
||||
S16MSB
|
||||
S32LSB
|
||||
S32MSB
|
||||
F32LSB
|
||||
F32MSB
|
||||
);
|
||||
|
||||
my %funcs;
|
||||
|
||||
my $custom_converters = 0;
|
||||
|
||||
|
||||
sub outputHeader {
|
||||
print <<EOF;
|
||||
/* DO NOT EDIT THIS FILE! It is generated code. */
|
||||
/* Please modify SDL/src/audio/sdlgenaudiocvt.pl instead. */
|
||||
|
||||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2006 Sam Lantinga
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Sam Lantinga
|
||||
slouken\@libsdl.org
|
||||
*/
|
||||
|
||||
#include "SDL_config.h"
|
||||
#include "SDL_audio.h"
|
||||
#include "SDL_audio_c.h"
|
||||
|
||||
/* Now the generated code... */
|
||||
|
||||
EOF
|
||||
|
||||
my @vals = ( 127, 255, 32767, 65535, 2147483647 );
|
||||
foreach (@vals) {
|
||||
my $val = $_;
|
||||
my $fval = 1.0 / $val;
|
||||
print("#define DIVBY${val} ${fval}f\n");
|
||||
}
|
||||
|
||||
print("\n");
|
||||
}
|
||||
|
||||
|
||||
sub splittype {
|
||||
my $t = shift;
|
||||
my ($signed, $size, $endian) = $t =~ /([USF])(\d+)([LM]SB|)/;
|
||||
my $float = ($signed eq 'F') ? 1 : 0;
|
||||
$signed = (($float) or ($signed eq 'S')) ? 1 : 0;
|
||||
$endian = 'NONE' if ($endian eq '');
|
||||
|
||||
my $ctype = '';
|
||||
if ($float) {
|
||||
$ctype = (($size == 32) ? 'float' : 'double');
|
||||
} else {
|
||||
$ctype = (($signed) ? 'S' : 'U') . "int${size}";
|
||||
}
|
||||
|
||||
return ($signed, $float, $size, $endian, $ctype);
|
||||
}
|
||||
|
||||
sub getSwapFunc {
|
||||
my ($size, $signed, $float, $endian, $val) = @_;
|
||||
my $BEorLE = (($endian eq 'MSB') ? 'BE' : 'LE');
|
||||
my $code = '';
|
||||
|
||||
if ($float) {
|
||||
$code = "SDL_SwapFloat${BEorLE}($val)";
|
||||
} else {
|
||||
if ($size > 8) {
|
||||
$code = "SDL_Swap${BEorLE}${size}($val)";
|
||||
} else {
|
||||
$code = $val;
|
||||
}
|
||||
|
||||
if (($signed) and (!$float)) {
|
||||
$code = "((Sint${size}) $code)";
|
||||
}
|
||||
}
|
||||
|
||||
return "${code}";
|
||||
}
|
||||
|
||||
|
||||
sub maxIntVal {
|
||||
my ($signed, $size) = @_;
|
||||
if ($signed) {
|
||||
if ($size == 8) {
|
||||
return 0x7F;
|
||||
} elsif ($size == 16) {
|
||||
return 0x7FFF;
|
||||
} elsif ($size == 32) {
|
||||
return 0x7FFFFFFF;
|
||||
}
|
||||
} else {
|
||||
if ($size == 8) {
|
||||
return 0xFF;
|
||||
} elsif ($size == 16) {
|
||||
return 0xFFFF;
|
||||
} elsif ($size == 32) {
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
die("bug in script.\n");
|
||||
}
|
||||
|
||||
sub getFloatToIntMult {
|
||||
my ($signed, $size) = @_;
|
||||
my $val = maxIntVal($signed, $size) . '.0';
|
||||
$val .= 'f' if ($size < 32);
|
||||
return $val;
|
||||
}
|
||||
|
||||
sub getIntToFloatDivBy {
|
||||
my ($signed, $size) = @_;
|
||||
return 'DIVBY' . maxIntVal($signed, $size);
|
||||
}
|
||||
|
||||
sub getSignFlipVal {
|
||||
my $size = shift;
|
||||
if ($size == 8) {
|
||||
return '0x80';
|
||||
} elsif ($size == 16) {
|
||||
return '0x8000';
|
||||
} elsif ($size == 32) {
|
||||
return '0x80000000';
|
||||
}
|
||||
|
||||
die("bug in script.\n");
|
||||
}
|
||||
|
||||
sub buildCvtFunc {
|
||||
my ($from, $to) = @_;
|
||||
my ($fsigned, $ffloat, $fsize, $fendian, $fctype) = splittype($from);
|
||||
my ($tsigned, $tfloat, $tsize, $tendian, $tctype) = splittype($to);
|
||||
my $diffs = 0;
|
||||
$diffs++ if ($fsize != $tsize);
|
||||
$diffs++ if ($fsigned != $tsigned);
|
||||
$diffs++ if ($ffloat != $tfloat);
|
||||
$diffs++ if ($fendian ne $tendian);
|
||||
|
||||
return if ($diffs == 0);
|
||||
|
||||
my $hashid = "$from/$to";
|
||||
if (1) { # !!! FIXME: if ($diffs > 1) {
|
||||
my $sym = "SDL_Convert_${from}_to_${to}";
|
||||
$funcs{$hashid} = $sym;
|
||||
$custom_converters++;
|
||||
|
||||
# Always unsigned for ints, for possible byteswaps.
|
||||
my $srctype = (($ffloat) ? 'float' : "Uint${fsize}");
|
||||
|
||||
print <<EOF;
|
||||
static void SDLCALL
|
||||
${sym}(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
||||
{
|
||||
int i;
|
||||
const $srctype *src;
|
||||
$tctype *dst;
|
||||
|
||||
#ifdef DEBUG_CONVERT
|
||||
fprintf(stderr, "Converting AUDIO_${from} to AUDIO_${to}.\\n");
|
||||
#endif
|
||||
|
||||
EOF
|
||||
|
||||
if ($fsize < $tsize) {
|
||||
my $mult = $tsize / $fsize;
|
||||
print <<EOF;
|
||||
src = (const $srctype *) (cvt->buf + cvt->len_cvt);
|
||||
dst = ($tctype *) (cvt->buf + cvt->len_cvt * $mult);
|
||||
for (i = cvt->len_cvt / sizeof ($srctype); i; --i, --src, --dst) {
|
||||
EOF
|
||||
} else {
|
||||
print <<EOF;
|
||||
src = (const $srctype *) cvt->buf;
|
||||
dst = ($tctype *) cvt->buf;
|
||||
for (i = cvt->len_cvt / sizeof ($srctype); i; --i, ++src, ++dst) {
|
||||
EOF
|
||||
}
|
||||
|
||||
# Have to convert to/from float/int.
|
||||
# !!! FIXME: cast through double for int32<->float?
|
||||
my $code = getSwapFunc($fsize, $fsigned, $ffloat, $fendian, '*src');
|
||||
if ($ffloat != $tfloat) {
|
||||
if ($ffloat) {
|
||||
my $mult = getFloatToIntMult($tsigned, $tsize);
|
||||
$code = "(($tctype) ($code * $mult))";
|
||||
} else {
|
||||
# $divby will be the reciprocal, to avoid pipeline stalls
|
||||
# from floating point division...so multiply it.
|
||||
my $divby = getIntToFloatDivBy($fsigned, $fsize);
|
||||
$code = "(((float) $code) * $divby)";
|
||||
}
|
||||
} else {
|
||||
# All integer conversions here.
|
||||
if ($fsigned != $tsigned) {
|
||||
my $signflipval = getSignFlipVal($fsize);
|
||||
$code = "(($code) ^ $signflipval)";
|
||||
}
|
||||
|
||||
my $shiftval = abs($fsize - $tsize);
|
||||
if ($fsize < $tsize) {
|
||||
$code = "((($tctype) $code) << $shiftval)";
|
||||
} elsif ($fsize > $tsize) {
|
||||
$code = "(($tctype) ($code >> $shiftval))";
|
||||
}
|
||||
}
|
||||
|
||||
my $swap = getSwapFunc($tsize, $tsigned, $tfloat, $tendian, 'val');
|
||||
|
||||
print <<EOF;
|
||||
const $tctype val = $code;
|
||||
*dst = ${swap};
|
||||
}
|
||||
|
||||
EOF
|
||||
|
||||
if ($fsize > $tsize) {
|
||||
my $divby = $fsize / $tsize;
|
||||
print(" cvt->len_cvt /= $divby;\n");
|
||||
} elsif ($fsize < $tsize) {
|
||||
my $mult = $tsize / $fsize;
|
||||
print(" cvt->len_cvt *= $mult;\n");
|
||||
}
|
||||
|
||||
print <<EOF;
|
||||
format = AUDIO_$to;
|
||||
if (cvt->filters[++cvt->filter_index]) {
|
||||
cvt->filters[cvt->filter_index] (cvt, format);
|
||||
}
|
||||
}
|
||||
|
||||
EOF
|
||||
|
||||
} else {
|
||||
if ($fsigned != $tsigned) {
|
||||
$funcs{$hashid} = 'SDL_ConvertSigned';
|
||||
} elsif ($ffloat != $tfloat) {
|
||||
$funcs{$hashid} = 'SDL_ConvertFloat';
|
||||
} elsif ($fsize != $tsize) {
|
||||
$funcs{$hashid} = 'SDL_ConvertSize';
|
||||
} elsif ($fendian ne $tendian) {
|
||||
$funcs{$hashid} = 'SDL_ConvertEndian';
|
||||
} else {
|
||||
die("error in script.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
outputHeader();
|
||||
|
||||
foreach (@audiotypes) {
|
||||
my $from = $_;
|
||||
foreach (@audiotypes) {
|
||||
my $to = $_;
|
||||
buildCvtFunc($from, $to);
|
||||
}
|
||||
}
|
||||
|
||||
print <<EOF;
|
||||
const SDL_AudioTypeFilters sdl_audio_type_filters[] =
|
||||
{
|
||||
EOF
|
||||
|
||||
foreach (@audiotypes) {
|
||||
my $from = $_;
|
||||
foreach (@audiotypes) {
|
||||
my $to = $_;
|
||||
if ($from ne $to) {
|
||||
my $hashid = "$from/$to";
|
||||
my $sym = $funcs{$hashid};
|
||||
print(" { AUDIO_$from, AUDIO_$to, $sym },\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
print <<EOF;
|
||||
};
|
||||
|
||||
|
||||
EOF
|
||||
|
||||
exit 0;
|
||||
|
||||
# end of sdlaudiocvt.pl ...
|
||||
|
|
@ -34,7 +34,7 @@ struct SDL_PrivateAudioData
|
|||
/* The file descriptor for the audio device */
|
||||
int audio_fd;
|
||||
|
||||
Uint16 audio_fmt; /* The app audio format */
|
||||
SDL_AudioFormat audio_fmt; /* The app audio format */
|
||||
Uint8 *mixbuf; /* The app mixing buffer */
|
||||
int ulaw_only; /* Flag -- does hardware only output U-law? */
|
||||
Uint8 *ulaw_buf; /* The U-law mixing buffer */
|
||||
|
|
|
@ -250,7 +250,7 @@ UMS_OpenAudio(_THIS, SDL_AudioSpec * spec)
|
|||
long bitsPerSample;
|
||||
long samplesPerSec;
|
||||
long success;
|
||||
Uint16 test_format;
|
||||
SDL_AudioFormat test_format;
|
||||
int frag_spec;
|
||||
UMSAudioDevice_ReturnCode rc;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue