Skip to content

Commit

Permalink
Added Timidity support for 32-bit signed and float audio formats
Browse files Browse the repository at this point in the history
  • Loading branch information
slouken committed Oct 21, 2017
1 parent 22caa40 commit f4ee931
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 7 deletions.
29 changes: 29 additions & 0 deletions timidity/output.c
Expand Up @@ -100,3 +100,32 @@ void s32tou16x(void *dp, Sint32 *lp, Sint32 c)
*sp++ = SDL_Swap16(0x8000 ^ (Uint16)(l));
}
}

void s32tof32(void *dp, Sint32 *lp, Sint32 c)
{
float *sp=(float *)(dp);
Sint32 l;
while (c--)
{
*sp++ = (float)(*lp++) / 2147483647.0f;
}
}

void s32tos32(void *dp, Sint32 *lp, Sint32 c)
{
Sint32 *sp=(Sint32 *)(dp);
Sint32 l;
while (c--)
{
*sp++ = (*lp++);
}
}

void s32tos32x(void *dp, Sint32 *lp, Sint32 c)
{
Sint32 *sp=(Sint32 *)(dp);
while (c--)
{
*sp++ = SDL_Swap32(*lp++);
}
}
20 changes: 16 additions & 4 deletions timidity/output.h
Expand Up @@ -15,6 +15,7 @@
#define PE_MONO 0x01 /* versus stereo */
#define PE_SIGNED 0x02 /* versus unsigned */
#define PE_16BIT 0x04 /* versus 8-bit */
#define PE_32BIT 0x08 /* versus 8-bit or 16-bit */

/* Conversion functions -- These overwrite the Sint32 data in *lp with
data in another format */
Expand All @@ -31,15 +32,26 @@ extern void s32tou16(void *dp, Sint32 *lp, Sint32 c);
extern void s32tos16x(void *dp, Sint32 *lp, Sint32 c);
extern void s32tou16x(void *dp, Sint32 *lp, Sint32 c);

/* 32-bit */
extern void s32tof32(void *dp, Sint32 *lp, Sint32 c);
extern void s32tos32(void *dp, Sint32 *lp, Sint32 c);

/* byte-exchanged 32-bit */
extern void s32tos32x(void *dp, Sint32 *lp, Sint32 c);

/* little-endian and big-endian specific */
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
#define s32tou16l s32tou16
#define s32tou16b s32tou16x
#define s32tos16l s32tos16
#define s32tos16b s32tos16x
#define s32tou16l s32tou16
#define s32tou16b s32tou16x
#define s32tos32l s32tos32
#define s32tos32b s32tos32x
#else
#define s32tou16l s32tou16x
#define s32tou16b s32tou16
#define s32tos16l s32tos16x
#define s32tos16b s32tos16
#define s32tou16l s32tou16x
#define s32tou16b s32tou16
#define s32tos32l s32tos32x
#define s32tos32b s32tos32
#endif
6 changes: 3 additions & 3 deletions timidity/playmidi.c
Expand Up @@ -664,9 +664,9 @@ int Timidity_PlaySome(MidiSong *song, void *stream, Sint32 len)
if (!song->playing)
return 0;

bytes_per_sample =
((song->encoding & PE_MONO) ? 1 : 2)
* ((song->encoding & PE_16BIT) ? 2 : 1);
bytes_per_sample = 1;
bytes_per_sample *= ((song->encoding & PE_32BIT) ? 4 : ((song->encoding & PE_16BIT) ? 2 : 1));
bytes_per_sample *= ((song->encoding & PE_MONO) ? 1 : 2);
samples = len / bytes_per_sample;

start_sample = song->current_sample;
Expand Down
11 changes: 11 additions & 0 deletions timidity/timidity.c
Expand Up @@ -490,6 +490,8 @@ MidiSong *Timidity_LoadSong(SDL_RWops *rw, SDL_AudioSpec *audio)
song->encoding = 0;
if ((audio->format & 0xFF) == 16)
song->encoding |= PE_16BIT;
else if ((audio->format & 0xFF) == 32)
song->encoding |= PE_32BIT;
if (audio->format & 0x8000)
song->encoding |= PE_SIGNED;
if (audio->channels == 1)
Expand Down Expand Up @@ -517,6 +519,15 @@ MidiSong *Timidity_LoadSong(SDL_RWops *rw, SDL_AudioSpec *audio)
case AUDIO_U16MSB:
song->write = s32tou16b;
break;
case AUDIO_S32LSB:
song->write = s32tos32l;
break;
case AUDIO_S32MSB:
song->write = s32tos32b;
break;
case AUDIO_F32SYS:
song->write = s32tof32;
break;
default:
SDL_SetError("Unsupported audio format");
return NULL;
Expand Down

0 comments on commit f4ee931

Please sign in to comment.