mirror of
https://github.com/libretro/retroluxury.git
synced 2024-11-23 07:39:47 +00:00
too much things to enumerate...
This commit is contained in:
parent
c2443374e4
commit
3bbe3424cd
9
.gitignore
vendored
9
.gitignore
vendored
@ -2,6 +2,15 @@
|
|||||||
*.exe
|
*.exe
|
||||||
*.dll
|
*.dll
|
||||||
*.so
|
*.so
|
||||||
|
*.png
|
||||||
|
*.tmx
|
||||||
|
*.tsx
|
||||||
*~
|
*~
|
||||||
rl_version.c
|
rl_version.c
|
||||||
boot_lua.h
|
boot_lua.h
|
||||||
|
bounce.h
|
||||||
|
sketch008.h
|
||||||
|
smile.h
|
||||||
|
GPATH
|
||||||
|
GRTAGS
|
||||||
|
GTAGS
|
||||||
|
@ -4,7 +4,7 @@ DEFINES=-DOUTSIDE_SPEEX -DRANDOM_PREFIX=speex -DEXPORT= -DFIXED_POINT
|
|||||||
#CFLAGS=-O3 --std=c99 -Wall $(INCLUDES) $(DEFINES) -fPIC
|
#CFLAGS=-O3 --std=c99 -Wall $(INCLUDES) $(DEFINES) -fPIC
|
||||||
CFLAGS=-O0 -g --std=c99 -Wall $(INCLUDES) $(DEFINES) -fPIC
|
CFLAGS=-O0 -g --std=c99 -Wall $(INCLUDES) $(DEFINES) -fPIC
|
||||||
|
|
||||||
OBJS=rl_backgrnd.o rl_base64.o rl_config.o rl_image.o rl_imgdata.o rl_pack.o rl_rand.o rl_resample.o rl_sound.o rl_snddata.o rl_sprite.o rl_version.o rl_xml.o external/resample.o
|
OBJS=rl_backgrnd.o rl_base64.o rl_config.o rl_image.o rl_imgdata.o rl_pack.o rl_rand.o rl_resample.o rl_sound.o rl_snddata.o rl_sprite.o rl_tiled.o rl_version.o rl_xml.o external/resample.o
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
gcc $(CFLAGS) -c $< -o $@
|
gcc $(CFLAGS) -c $< -o $@
|
||||||
|
@ -7,7 +7,8 @@
|
|||||||
//#define RL_BACKGRND_STRETCH 1
|
//#define RL_BACKGRND_STRETCH 1
|
||||||
//#define RL_BACKGRND_EXPAND 2
|
//#define RL_BACKGRND_EXPAND 2
|
||||||
|
|
||||||
#define RL_COLOR( r, g, b ) ( ( r * 32 / 256 ) << 11 | ( g * 64 / 256 ) << 5 | ( b * 32 / 256 ) )
|
#define RL_COLOR( r, g, b ) ( ( ( r ) * 32 / 256 ) << 11 | ( ( g ) * 64 / 256 ) << 5 | ( ( b ) * 32 / 256 ) )
|
||||||
|
#define RL_COLOR_2( rgb ) RL_COLOR( ( rgb >> 16 ) & 255, ( rgb >> 8 ) & 255, rgb & 255 )
|
||||||
|
|
||||||
int rl_backgrnd_create( int width, int height, int aspect );
|
int rl_backgrnd_create( int width, int height, int aspect );
|
||||||
void rl_backgrnd_destroy( void );
|
void rl_backgrnd_destroy( void );
|
||||||
|
@ -1,27 +1,27 @@
|
|||||||
#include <rl_config.h>
|
#include <rl_config.h>
|
||||||
|
|
||||||
static const rl_config_t config =
|
static const rl_config_t config =
|
||||||
{
|
{
|
||||||
RL_VERSION_MAJOR,
|
RL_VERSION_MAJOR,
|
||||||
RL_VERSION_MINOR,
|
RL_VERSION_MINOR,
|
||||||
RL_BACKGRND_MARGIN,
|
RL_BACKGRND_MARGIN,
|
||||||
RL_MAX_SPRITES,
|
RL_MAX_SPRITES,
|
||||||
RL_BG_SAVE_SIZE,
|
RL_BG_SAVE_SIZE,
|
||||||
RL_FRAME_RATE,
|
RL_FRAME_RATE,
|
||||||
RL_SAMPLE_RATE,
|
RL_SAMPLE_RATE,
|
||||||
RL_SAMPLES_PER_FRAME,
|
RL_SAMPLES_PER_FRAME,
|
||||||
RL_RESAMPLER_QUALITY,
|
RL_RESAMPLER_QUALITY,
|
||||||
RL_MAX_VOICES,
|
RL_MAX_VOICES,
|
||||||
RL_OGG_INCREMENT,
|
RL_OGG_INCREMENT,
|
||||||
#ifdef RL_OGG_VORBIS
|
#ifdef RL_OGG_VORBIS
|
||||||
1,
|
1,
|
||||||
#else
|
#else
|
||||||
0,
|
0,
|
||||||
#endif
|
#endif
|
||||||
RL_USERDATA_COUNT
|
RL_USERDATA_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
const rl_config_t* rl_get_config( void )
|
const rl_config_t* rl_get_config( void )
|
||||||
{
|
{
|
||||||
return &config;
|
return &config;
|
||||||
}
|
}
|
||||||
|
@ -10,3 +10,16 @@ static inline uint32_t djb2( const char* str )
|
|||||||
|
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline uint32_t djb2_length( const char* str, size_t length )
|
||||||
|
{
|
||||||
|
const unsigned char* aux = (const unsigned char*)str;
|
||||||
|
uint32_t hash = 5381;
|
||||||
|
|
||||||
|
while ( length-- )
|
||||||
|
{
|
||||||
|
hash = ( hash << 5 ) + hash + *aux++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <rl_imgdata.h>
|
#include <rl_imgdata.h>
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
An image with RLE-encoded pixels and per-pixel alpha of 0, 25, 50, 75 and 100%.
|
An image with RLE-encoded pixels and per-pixel alpha of 0, 25, 50, 75 and 100%.
|
||||||
|
@ -1,86 +1,86 @@
|
|||||||
#include <rl_resample.h>
|
#include <rl_resample.h>
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
#include "external/speex_resampler.h"
|
#include "external/speex_resampler.h"
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#if RL_RESAMPLER_QUALITY < SPEEX_RESAMPLER_QUALITY_MIN || RL_RESAMPLER_QUALITY > SPEEX_RESAMPLER_QUALITY_MAX
|
#if RL_RESAMPLER_QUALITY < SPEEX_RESAMPLER_QUALITY_MIN || RL_RESAMPLER_QUALITY > SPEEX_RESAMPLER_QUALITY_MAX
|
||||||
#error Invalid quality value in RL_RESAMPLER_QUALITY
|
#error Invalid quality value in RL_RESAMPLER_QUALITY
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static char passthrough = 0;
|
static char passthrough = 0;
|
||||||
|
|
||||||
rl_resampler_t* rl_resampler_create( unsigned in_freq )
|
rl_resampler_t* rl_resampler_create( unsigned in_freq )
|
||||||
{
|
{
|
||||||
if ( in_freq != RL_SAMPLE_RATE )
|
if ( in_freq != RL_SAMPLE_RATE )
|
||||||
{
|
{
|
||||||
return (rl_resampler_t*)speex_resampler_init( 2, in_freq, RL_SAMPLE_RATE, RL_RESAMPLER_QUALITY, NULL );
|
return (rl_resampler_t*)speex_resampler_init( 2, in_freq, RL_SAMPLE_RATE, RL_RESAMPLER_QUALITY, NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
return (rl_resampler_t*)&passthrough;
|
return (rl_resampler_t*)&passthrough;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rl_resampler_destroy( rl_resampler_t* resampler )
|
void rl_resampler_destroy( rl_resampler_t* resampler )
|
||||||
{
|
{
|
||||||
if ( resampler != (rl_resampler_t*)&passthrough )
|
if ( resampler != (rl_resampler_t*)&passthrough )
|
||||||
{
|
{
|
||||||
speex_resampler_destroy( (SpeexResamplerState*)resampler );
|
speex_resampler_destroy( (SpeexResamplerState*)resampler );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t rl_resampler_out_samples( rl_resampler_t* resampler, size_t in_samples )
|
size_t rl_resampler_out_samples( rl_resampler_t* resampler, size_t in_samples )
|
||||||
{
|
{
|
||||||
if ( resampler != (rl_resampler_t*)&passthrough )
|
if ( resampler != (rl_resampler_t*)&passthrough )
|
||||||
{
|
{
|
||||||
SpeexResamplerState* st = (SpeexResamplerState*)resampler;
|
SpeexResamplerState* st = (SpeexResamplerState*)resampler;
|
||||||
spx_uint32_t in_rate, out_rate;
|
spx_uint32_t in_rate, out_rate;
|
||||||
|
|
||||||
speex_resampler_get_rate( st, &in_rate, &out_rate );
|
speex_resampler_get_rate( st, &in_rate, &out_rate );
|
||||||
return in_samples * out_rate / in_rate;
|
return in_samples * out_rate / in_rate;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return in_samples;
|
return in_samples;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t rl_resampler_in_samples( rl_resampler_t* resampler, size_t out_samples )
|
size_t rl_resampler_in_samples( rl_resampler_t* resampler, size_t out_samples )
|
||||||
{
|
{
|
||||||
if ( resampler != (rl_resampler_t*)&passthrough )
|
if ( resampler != (rl_resampler_t*)&passthrough )
|
||||||
{
|
{
|
||||||
SpeexResamplerState* st = (SpeexResamplerState*)resampler;
|
SpeexResamplerState* st = (SpeexResamplerState*)resampler;
|
||||||
spx_uint32_t in_rate, out_rate;
|
spx_uint32_t in_rate, out_rate;
|
||||||
|
|
||||||
speex_resampler_get_rate( st, &in_rate, &out_rate );
|
speex_resampler_get_rate( st, &in_rate, &out_rate );
|
||||||
return out_samples * in_rate / out_rate;
|
return out_samples * in_rate / out_rate;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return out_samples;
|
return out_samples;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t rl_resampler_resample( rl_resampler_t* resampler, const int16_t* in_buffer, size_t in_samples, int16_t* out_buffer, size_t out_samples )
|
size_t rl_resampler_resample( rl_resampler_t* resampler, const int16_t* in_buffer, size_t in_samples, int16_t* out_buffer, size_t out_samples )
|
||||||
{
|
{
|
||||||
if ( resampler != (rl_resampler_t*)&passthrough )
|
if ( resampler != (rl_resampler_t*)&passthrough )
|
||||||
{
|
{
|
||||||
spx_uint32_t in_len = in_samples;
|
spx_uint32_t in_len = in_samples;
|
||||||
spx_uint32_t out_len = out_samples;
|
spx_uint32_t out_len = out_samples;
|
||||||
|
|
||||||
int error = speex_resampler_process_int( (SpeexResamplerState*)resampler, 0, in_buffer, &in_len, out_buffer, &out_len );
|
int error = speex_resampler_process_int( (SpeexResamplerState*)resampler, 0, in_buffer, &in_len, out_buffer, &out_len );
|
||||||
return error == RESAMPLER_ERR_SUCCESS ? out_len : 0;
|
return error == RESAMPLER_ERR_SUCCESS ? out_len : 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( in_samples > out_samples )
|
if ( in_samples > out_samples )
|
||||||
{
|
{
|
||||||
in_samples = out_samples;
|
in_samples = out_samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy( out_buffer, in_buffer, in_samples * sizeof( int16_t ) );
|
memcpy( out_buffer, in_buffer, in_samples * sizeof( int16_t ) );
|
||||||
return in_samples;
|
return in_samples;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,23 +1,23 @@
|
|||||||
#ifndef RL_RESAMPLE_H
|
#ifndef RL_RESAMPLE_H
|
||||||
#define RL_RESAMPLE_H
|
#define RL_RESAMPLE_H
|
||||||
|
|
||||||
#include <rl_userdata.h>
|
#include <rl_userdata.h>
|
||||||
#include <rl_imgdata.h>
|
#include <rl_imgdata.h>
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
typedef void rl_resampler_t;
|
typedef void rl_resampler_t;
|
||||||
|
|
||||||
/* Creates a resampler. */
|
/* Creates a resampler. */
|
||||||
rl_resampler_t* rl_resampler_create( unsigned in_freq );
|
rl_resampler_t* rl_resampler_create( unsigned in_freq );
|
||||||
/* Destroys a resampler. */
|
/* Destroys a resampler. */
|
||||||
void rl_resampler_destroy( rl_resampler_t* resampler );
|
void rl_resampler_destroy( rl_resampler_t* resampler );
|
||||||
|
|
||||||
/* Returns how much samples an output buffer must have to resample an input buffer with this number of samples. */
|
/* Returns how much samples an output buffer must have to resample an input buffer with this number of samples. */
|
||||||
size_t rl_resampler_out_samples( rl_resampler_t* resampler, size_t in_samples );
|
size_t rl_resampler_out_samples( rl_resampler_t* resampler, size_t in_samples );
|
||||||
/* Returns how much samples an input buffer must have to fill an output buffer with this number of samples. */
|
/* Returns how much samples an input buffer must have to fill an output buffer with this number of samples. */
|
||||||
size_t rl_resampler_in_samples( rl_resampler_t* resampler, size_t out_samples );
|
size_t rl_resampler_in_samples( rl_resampler_t* resampler, size_t out_samples );
|
||||||
/* Resamples the input buffer into the output buffer. */
|
/* Resamples the input buffer into the output buffer. */
|
||||||
size_t rl_resampler_resample( rl_resampler_t* resampler, const int16_t* in_buffer, size_t in_samples, int16_t* out_buffer, size_t out_samples );
|
size_t rl_resampler_resample( rl_resampler_t* resampler, const int16_t* in_buffer, size_t in_samples, int16_t* out_buffer, size_t out_samples );
|
||||||
|
|
||||||
#endif /* RL_RESAMPLE_H */
|
#endif /* RL_RESAMPLE_H */
|
||||||
|
450
src/rl_snddata.c
450
src/rl_snddata.c
@ -1,225 +1,225 @@
|
|||||||
#include <rl_snddata.h>
|
#include <rl_snddata.h>
|
||||||
#include <rl_resample.h>
|
#include <rl_resample.h>
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <rl_endian.inl>
|
#include <rl_endian.inl>
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
/* header */
|
/* header */
|
||||||
char chunkid[ 4 ];
|
char chunkid[ 4 ];
|
||||||
uint32_t chunksize;
|
uint32_t chunksize;
|
||||||
char format[ 4 ];
|
char format[ 4 ];
|
||||||
/* fmt */
|
/* fmt */
|
||||||
char subchunk1id[ 4 ];
|
char subchunk1id[ 4 ];
|
||||||
uint32_t subchunk1size;
|
uint32_t subchunk1size;
|
||||||
uint16_t audioformat;
|
uint16_t audioformat;
|
||||||
uint16_t numchannels;
|
uint16_t numchannels;
|
||||||
uint32_t samplerate;
|
uint32_t samplerate;
|
||||||
uint32_t byterate;
|
uint32_t byterate;
|
||||||
uint16_t blockalign;
|
uint16_t blockalign;
|
||||||
uint16_t bitspersample;
|
uint16_t bitspersample;
|
||||||
/* data */
|
/* data */
|
||||||
char subchunk2id[ 4 ];
|
char subchunk2id[ 4 ];
|
||||||
uint32_t subchunk2size;
|
uint32_t subchunk2size;
|
||||||
uint8_t data[ 0 ];
|
uint8_t data[ 0 ];
|
||||||
|
|
||||||
}
|
}
|
||||||
wave_t;
|
wave_t;
|
||||||
|
|
||||||
int rl_snddata_create( rl_snddata_t* snddata, const void* data, size_t size )
|
int rl_snddata_create( rl_snddata_t* snddata, const void* data, size_t size )
|
||||||
{
|
{
|
||||||
const wave_t* wave = (const wave_t*)data;
|
const wave_t* wave = (const wave_t*)data;
|
||||||
|
|
||||||
if ( wave->chunkid[ 0 ] != 'R' || wave->chunkid[ 1 ] != 'I' || wave->chunkid[ 2 ] != 'F' || wave->chunkid[ 3 ] != 'F' )
|
if ( wave->chunkid[ 0 ] != 'R' || wave->chunkid[ 1 ] != 'I' || wave->chunkid[ 2 ] != 'F' || wave->chunkid[ 3 ] != 'F' )
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( wave->format[ 0 ] != 'W' || wave->format[ 1 ] != 'A' || wave->format[ 2 ] != 'V' || wave->format[ 3 ] != 'E' )
|
if ( wave->format[ 0 ] != 'W' || wave->format[ 1 ] != 'A' || wave->format[ 2 ] != 'V' || wave->format[ 3 ] != 'E' )
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( wave->subchunk1id[ 0 ] != 'f' || wave->subchunk1id[ 1 ] != 'm' || wave->subchunk1id[ 2 ] != 't' || wave->subchunk1id[ 3 ] != ' ' )
|
if ( wave->subchunk1id[ 0 ] != 'f' || wave->subchunk1id[ 1 ] != 'm' || wave->subchunk1id[ 2 ] != 't' || wave->subchunk1id[ 3 ] != ' ' )
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( wave->subchunk2id[ 0 ] != 'd' || wave->subchunk2id[ 1 ] != 'a' || wave->subchunk2id[ 2 ] != 't' || wave->subchunk2id[ 3 ] != 'a' )
|
if ( wave->subchunk2id[ 0 ] != 'd' || wave->subchunk2id[ 1 ] != 'a' || wave->subchunk2id[ 2 ] != 't' || wave->subchunk2id[ 3 ] != 'a' )
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
snddata->bps = le16( wave->bitspersample );
|
snddata->bps = le16( wave->bitspersample );
|
||||||
snddata->channels = le16( wave->numchannels );
|
snddata->channels = le16( wave->numchannels );
|
||||||
snddata->freq = le32( wave->samplerate );
|
snddata->freq = le32( wave->samplerate );
|
||||||
|
|
||||||
if ( le16( wave->audioformat ) != 1 )
|
if ( le16( wave->audioformat ) != 1 )
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( snddata->channels != 1 && snddata->channels != 2 )
|
if ( snddata->channels != 1 && snddata->channels != 2 )
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( snddata->bps != 8 && snddata->bps != 16 )
|
if ( snddata->bps != 8 && snddata->bps != 16 )
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
snddata->size = le32( wave->subchunk2size );
|
snddata->size = le32( wave->subchunk2size );
|
||||||
snddata->samples = malloc( snddata->size );
|
snddata->samples = malloc( snddata->size );
|
||||||
|
|
||||||
if ( snddata->samples )
|
if ( snddata->samples )
|
||||||
{
|
{
|
||||||
memcpy( (void*)snddata->samples, (void*)wave->data, snddata->size );
|
memcpy( (void*)snddata->samples, (void*)wave->data, snddata->size );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int16_t* rl_snddata_encode( size_t* out_samples, const rl_snddata_t* snddata )
|
const int16_t* rl_snddata_encode( size_t* out_samples, const rl_snddata_t* snddata )
|
||||||
{
|
{
|
||||||
int16_t* out_buffer;
|
int16_t* out_buffer;
|
||||||
size_t in_samples;
|
size_t in_samples;
|
||||||
|
|
||||||
if ( snddata->bps == 8 )
|
if ( snddata->bps == 8 )
|
||||||
{
|
{
|
||||||
if ( snddata->channels == 1 )
|
if ( snddata->channels == 1 )
|
||||||
{
|
{
|
||||||
/* 8 bps, mono. */
|
/* 8 bps, mono. */
|
||||||
in_samples = snddata->size;
|
in_samples = snddata->size;
|
||||||
*out_samples = in_samples * 2;
|
*out_samples = in_samples * 2;
|
||||||
out_buffer = (int16_t*)malloc( *out_samples * sizeof( int16_t ) );
|
out_buffer = (int16_t*)malloc( *out_samples * sizeof( int16_t ) );
|
||||||
|
|
||||||
if ( !out_buffer )
|
if ( !out_buffer )
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t* samples = out_buffer;
|
int16_t* samples = out_buffer;
|
||||||
const uint8_t* begin = (const uint8_t*)snddata->samples;
|
const uint8_t* begin = (const uint8_t*)snddata->samples;
|
||||||
const uint8_t* end = begin + in_samples;
|
const uint8_t* end = begin + in_samples;
|
||||||
|
|
||||||
while ( begin < end )
|
while ( begin < end )
|
||||||
{
|
{
|
||||||
int sample = *begin++;
|
int sample = *begin++;
|
||||||
sample = sample * 65792 / 256 - 32768;
|
sample = sample * 65792 / 256 - 32768;
|
||||||
*samples++ = sample;
|
*samples++ = sample;
|
||||||
*samples++ = sample;
|
*samples++ = sample;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* 8 bps, stereo. */
|
/* 8 bps, stereo. */
|
||||||
in_samples = snddata->size;
|
in_samples = snddata->size;
|
||||||
*out_samples = in_samples;
|
*out_samples = in_samples;
|
||||||
out_buffer = (int16_t*)malloc( *out_samples * sizeof( int16_t ) );
|
out_buffer = (int16_t*)malloc( *out_samples * sizeof( int16_t ) );
|
||||||
|
|
||||||
if ( !out_buffer )
|
if ( !out_buffer )
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t* samples = out_buffer;
|
int16_t* samples = out_buffer;
|
||||||
const uint8_t* begin = (const uint8_t*)snddata->samples;
|
const uint8_t* begin = (const uint8_t*)snddata->samples;
|
||||||
const uint8_t* end = begin + in_samples;
|
const uint8_t* end = begin + in_samples;
|
||||||
|
|
||||||
while ( begin < end )
|
while ( begin < end )
|
||||||
{
|
{
|
||||||
int sample = *begin++;
|
int sample = *begin++;
|
||||||
sample = sample * 65792 / 256 - 32768;
|
sample = sample * 65792 / 256 - 32768;
|
||||||
*samples++ = sample;
|
*samples++ = sample;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( snddata->channels == 1 )
|
if ( snddata->channels == 1 )
|
||||||
{
|
{
|
||||||
/* 16 bps, mono. */
|
/* 16 bps, mono. */
|
||||||
in_samples = snddata->size / 2;
|
in_samples = snddata->size / 2;
|
||||||
*out_samples = in_samples * 2;
|
*out_samples = in_samples * 2;
|
||||||
out_buffer = (int16_t*)malloc( *out_samples * sizeof( int16_t ) );
|
out_buffer = (int16_t*)malloc( *out_samples * sizeof( int16_t ) );
|
||||||
|
|
||||||
if ( !out_buffer )
|
if ( !out_buffer )
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t* samples = out_buffer;
|
int16_t* samples = out_buffer;
|
||||||
const uint16_t* begin = (const uint16_t*)snddata->samples;
|
const uint16_t* begin = (const uint16_t*)snddata->samples;
|
||||||
const uint16_t* end = begin + in_samples;
|
const uint16_t* end = begin + in_samples;
|
||||||
|
|
||||||
while ( begin < end )
|
while ( begin < end )
|
||||||
{
|
{
|
||||||
int16_t sample = le16( *begin++ );
|
int16_t sample = le16( *begin++ );
|
||||||
*samples++ = sample;
|
*samples++ = sample;
|
||||||
*samples++ = sample;
|
*samples++ = sample;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* 16 bps, stereo. */
|
/* 16 bps, stereo. */
|
||||||
in_samples = snddata->size / 2;
|
in_samples = snddata->size / 2;
|
||||||
*out_samples = in_samples;
|
*out_samples = in_samples;
|
||||||
out_buffer = (int16_t*)malloc( *out_samples * sizeof( int16_t ) );
|
out_buffer = (int16_t*)malloc( *out_samples * sizeof( int16_t ) );
|
||||||
|
|
||||||
if ( !out_buffer )
|
if ( !out_buffer )
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t* samples = out_buffer;
|
int16_t* samples = out_buffer;
|
||||||
const uint16_t* begin = (const uint16_t*)snddata->samples;
|
const uint16_t* begin = (const uint16_t*)snddata->samples;
|
||||||
const uint16_t* end = begin + in_samples;
|
const uint16_t* end = begin + in_samples;
|
||||||
|
|
||||||
while ( begin < end )
|
while ( begin < end )
|
||||||
{
|
{
|
||||||
*samples++ = le16( *begin++ );
|
*samples++ = le16( *begin++ );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( snddata->freq != RL_SAMPLE_RATE )
|
if ( snddata->freq != RL_SAMPLE_RATE )
|
||||||
{
|
{
|
||||||
rl_resampler_t* resampler = rl_resampler_create( snddata->freq );
|
rl_resampler_t* resampler = rl_resampler_create( snddata->freq );
|
||||||
|
|
||||||
if ( !resampler )
|
if ( !resampler )
|
||||||
{
|
{
|
||||||
free( out_buffer );
|
free( out_buffer );
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t new_samples = rl_resampler_out_samples( resampler, *out_samples );
|
size_t new_samples = rl_resampler_out_samples( resampler, *out_samples );
|
||||||
int16_t* new_buffer = (int16_t*)malloc( new_samples * sizeof( int16_t ) );
|
int16_t* new_buffer = (int16_t*)malloc( new_samples * sizeof( int16_t ) );
|
||||||
|
|
||||||
if ( !new_buffer )
|
if ( !new_buffer )
|
||||||
{
|
{
|
||||||
rl_resampler_destroy( resampler );
|
rl_resampler_destroy( resampler );
|
||||||
free( out_buffer );
|
free( out_buffer );
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( rl_resampler_resample( resampler, out_buffer, *out_samples, new_buffer, new_samples ) != new_samples )
|
if ( rl_resampler_resample( resampler, out_buffer, *out_samples, new_buffer, new_samples ) != new_samples )
|
||||||
{
|
{
|
||||||
free( new_buffer );
|
free( new_buffer );
|
||||||
rl_resampler_destroy( resampler );
|
rl_resampler_destroy( resampler );
|
||||||
free( out_buffer );
|
free( out_buffer );
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
free( out_buffer );
|
free( out_buffer );
|
||||||
out_buffer = new_buffer;
|
out_buffer = new_buffer;
|
||||||
*out_samples = new_samples;
|
*out_samples = new_samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
return out_buffer;
|
return out_buffer;
|
||||||
}
|
}
|
||||||
|
@ -1,27 +1,28 @@
|
|||||||
#ifndef RL_SNDDATA_H
|
#ifndef RL_SNDDATA_H
|
||||||
#define RL_SNDDATA_H
|
#define RL_SNDDATA_H
|
||||||
|
|
||||||
#include <rl_userdata.h>
|
#include <rl_userdata.h>
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
typedef struct
|
|
||||||
{
|
typedef struct
|
||||||
rl_userdata_t ud;
|
{
|
||||||
|
rl_userdata_t ud;
|
||||||
int bps; /* bits per sample */
|
|
||||||
int channels; /* number of channels */
|
int bps; /* bits per sample */
|
||||||
int freq; /* frequency */
|
int channels; /* number of channels */
|
||||||
|
int freq; /* frequency */
|
||||||
size_t size;
|
|
||||||
const void* samples;
|
size_t size;
|
||||||
}
|
const void* samples;
|
||||||
rl_snddata_t;
|
}
|
||||||
|
rl_snddata_t;
|
||||||
int rl_snddata_create( rl_snddata_t* snddata, const void* data, size_t size );
|
|
||||||
#define rl_snddata_destroy( snddata ) do { free( (void*)( snddata )->samples ); } while ( 0 )
|
int rl_snddata_create( rl_snddata_t* snddata, const void* data, size_t size );
|
||||||
|
#define rl_snddata_destroy( snddata ) do { free( (void*)( snddata )->samples ); } while ( 0 )
|
||||||
const int16_t* rl_snddata_encode( size_t* out_samples, const rl_snddata_t* snddata );
|
|
||||||
|
const int16_t* rl_snddata_encode( size_t* out_samples, const rl_snddata_t* snddata );
|
||||||
#endif /* RL_SNDDATA_H */
|
|
||||||
|
#endif /* RL_SNDDATA_H */
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
/* Reasons passed to the stop callback. */
|
/* Reasons passed to the stop callback. */
|
||||||
#define RL_SOUND_FINISHED 0
|
#define RL_SOUND_FINISHED 0
|
||||||
|
304
src/rl_xml.c
304
src/rl_xml.c
@ -1,152 +1,152 @@
|
|||||||
#include <rl_xml.h>
|
#include <rl_xml.h>
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
static inline void skip_to_tag( const char** xml )
|
static inline void skip_to_tag( const char** xml )
|
||||||
{
|
{
|
||||||
const char* aux = *xml;
|
const char* aux = *xml;
|
||||||
|
|
||||||
while ( *aux != '<' && *aux )
|
while ( *aux != '<' && *aux )
|
||||||
{
|
{
|
||||||
aux++;
|
aux++;
|
||||||
}
|
}
|
||||||
|
|
||||||
*xml = aux;
|
*xml = aux;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void skip_name( const char** xml )
|
static inline void skip_name( const char** xml )
|
||||||
{
|
{
|
||||||
const char* aux = *xml;
|
const char* aux = *xml;
|
||||||
|
|
||||||
while ( !isspace( *aux ) && *aux != '>' && *aux != '=' && *aux )
|
while ( !isspace( *aux ) && *aux != '>' && *aux != '=' && *aux )
|
||||||
{
|
{
|
||||||
aux++;
|
aux++;
|
||||||
}
|
}
|
||||||
|
|
||||||
*xml = aux;
|
*xml = aux;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void skip_spaces( const char** xml )
|
static inline void skip_spaces( const char** xml )
|
||||||
{
|
{
|
||||||
const char* aux = *xml;
|
const char* aux = *xml;
|
||||||
|
|
||||||
while ( isspace( *aux ) )
|
while ( isspace( *aux ) )
|
||||||
{
|
{
|
||||||
aux++;
|
aux++;
|
||||||
}
|
}
|
||||||
|
|
||||||
*xml = aux;
|
*xml = aux;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CHECK( stmt ) do { int res = stmt; if ( res ) return res; } while ( 0 )
|
#define CHECK( stmt ) do { int res = stmt; if ( res ) return res; } while ( 0 )
|
||||||
|
|
||||||
static int parse( const char* xml, const char* end, rl_xmlhandlers_t* handlers )
|
static int parse( const char* xml, const char* end, rl_xmlhandlers_t* handlers )
|
||||||
{
|
{
|
||||||
CHECK( handlers->start_document( handlers ) );
|
CHECK( handlers->start_document( handlers ) );
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
const char* text = xml;
|
const char* text = xml;
|
||||||
skip_to_tag( &xml );
|
skip_to_tag( &xml );
|
||||||
|
|
||||||
if ( xml != text )
|
if ( xml != text )
|
||||||
{
|
{
|
||||||
CHECK( handlers->characters( handlers, text, xml - text ) );
|
CHECK( handlers->characters( handlers, text, xml - text ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( *xml != '<' )
|
if ( *xml != '<' )
|
||||||
{
|
{
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( xml[ 1 ] == '/' )
|
if ( xml[ 1 ] == '/' )
|
||||||
{
|
{
|
||||||
const char* name = xml += 2;
|
const char* name = xml += 2;
|
||||||
skip_name( &xml );
|
skip_name( &xml );
|
||||||
CHECK( handlers->end_element( handlers, name, xml - name ) );
|
CHECK( handlers->end_element( handlers, name, xml - name ) );
|
||||||
skip_spaces( &xml );
|
skip_spaces( &xml );
|
||||||
|
|
||||||
if ( *xml != '>' )
|
if ( *xml != '>' )
|
||||||
{
|
{
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
xml++;
|
xml++;
|
||||||
}
|
}
|
||||||
else if ( xml[ 1 ] == '?' )
|
else if ( xml[ 1 ] == '?' )
|
||||||
{
|
{
|
||||||
xml = strstr( xml + 2, "?>" );
|
xml = strstr( xml + 2, "?>" );
|
||||||
|
|
||||||
if ( !xml )
|
if ( !xml )
|
||||||
{
|
{
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
xml += 2;
|
xml += 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const char* name = ++xml;
|
const char* name = ++xml;
|
||||||
skip_name( &xml );
|
skip_name( &xml );
|
||||||
size_t name_length = xml - name;
|
size_t name_length = xml - name;
|
||||||
CHECK( handlers->start_element( handlers, name, name_length ) );
|
CHECK( handlers->start_element( handlers, name, name_length ) );
|
||||||
|
|
||||||
skip_spaces( &xml );
|
skip_spaces( &xml );
|
||||||
|
|
||||||
while ( *xml != '>' && *xml != '/' )
|
while ( *xml != '>' && *xml != '/' )
|
||||||
{
|
{
|
||||||
const char* key = xml;
|
const char* key = xml;
|
||||||
skip_name( &xml );
|
skip_name( &xml );
|
||||||
size_t key_length = xml - key;
|
size_t key_length = xml - key;
|
||||||
|
|
||||||
skip_spaces( &xml );
|
skip_spaces( &xml );
|
||||||
|
|
||||||
if ( *xml != '=' )
|
if ( *xml != '=' )
|
||||||
{
|
{
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
xml++;
|
xml++;
|
||||||
skip_spaces( &xml );
|
skip_spaces( &xml );
|
||||||
char quote = *xml++;
|
char quote = *xml++;
|
||||||
const char* value = xml;
|
const char* value = xml;
|
||||||
|
|
||||||
xml = strchr( xml, quote );
|
xml = strchr( xml, quote );
|
||||||
|
|
||||||
if ( !xml )
|
if ( !xml )
|
||||||
{
|
{
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
CHECK( handlers->attribute( handlers, key, key_length, value, xml - value ) );
|
CHECK( handlers->attribute( handlers, key, key_length, value, xml - value ) );
|
||||||
|
|
||||||
xml++;
|
xml++;
|
||||||
skip_spaces( &xml );
|
skip_spaces( &xml );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( *xml == '/' )
|
if ( *xml == '/' )
|
||||||
{
|
{
|
||||||
CHECK( handlers->end_element( handlers, name, name_length ) );
|
CHECK( handlers->end_element( handlers, name, name_length ) );
|
||||||
xml++;
|
xml++;
|
||||||
skip_spaces( &xml );
|
skip_spaces( &xml );
|
||||||
|
|
||||||
if ( *xml != '>' )
|
if ( *xml != '>' )
|
||||||
{
|
{
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
xml++;
|
xml++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while ( *xml );
|
while ( *xml );
|
||||||
|
|
||||||
out:
|
out:
|
||||||
return handlers->end_document( handlers );
|
return handlers->end_document( handlers );
|
||||||
}
|
}
|
||||||
|
|
||||||
int rl_xml_parse( const char* xml, size_t length, rl_xmlhandlers_t* handlers )
|
int rl_xml_parse( const char* xml, size_t length, rl_xmlhandlers_t* handlers )
|
||||||
{
|
{
|
||||||
return parse( xml, xml + length, handlers );
|
return parse( xml, xml + length, handlers );
|
||||||
}
|
}
|
||||||
|
48
src/rl_xml.h
48
src/rl_xml.h
@ -1,24 +1,24 @@
|
|||||||
#ifndef RL_XML_H
|
#ifndef RL_XML_H
|
||||||
#define RL_XML_H
|
#define RL_XML_H
|
||||||
|
|
||||||
#include <rl_userdata.h>
|
#include <rl_userdata.h>
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
typedef struct rl_xmlhandlers_t rl_xmlhandlers_t;
|
typedef struct rl_xmlhandlers_t rl_xmlhandlers_t;
|
||||||
|
|
||||||
struct rl_xmlhandlers_t
|
struct rl_xmlhandlers_t
|
||||||
{
|
{
|
||||||
rl_userdata_t ud;
|
rl_userdata_t ud;
|
||||||
|
|
||||||
int ( *start_document )( rl_xmlhandlers_t* handlers );
|
int ( *start_document )( rl_xmlhandlers_t* handlers );
|
||||||
int ( *end_document )( rl_xmlhandlers_t* handlers );
|
int ( *end_document )( rl_xmlhandlers_t* handlers );
|
||||||
int ( *start_element )( rl_xmlhandlers_t* handlers, const char* name, size_t length );
|
int ( *start_element )( rl_xmlhandlers_t* handlers, const char* name, size_t length );
|
||||||
int ( *end_element )( rl_xmlhandlers_t* handlers, const char* name, size_t length );
|
int ( *end_element )( rl_xmlhandlers_t* handlers, const char* name, size_t length );
|
||||||
int ( *attribute )( rl_xmlhandlers_t* handlers, const char* key, size_t key_length, const char* value, size_t value_length );
|
int ( *attribute )( rl_xmlhandlers_t* handlers, const char* key, size_t key_length, const char* value, size_t value_length );
|
||||||
int ( *characters )( rl_xmlhandlers_t* handlers, const char* text, size_t length );
|
int ( *characters )( rl_xmlhandlers_t* handlers, const char* text, size_t length );
|
||||||
};
|
};
|
||||||
|
|
||||||
int rl_xml_parse( const char* xml, size_t length, rl_xmlhandlers_t* handlers );
|
int rl_xml_parse( const char* xml, size_t length, rl_xmlhandlers_t* handlers );
|
||||||
|
|
||||||
#endif /* RL_XML_H */
|
#endif /* RL_XML_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user