- Implementada polifonia en Chirping
- Arreglats un montó de warnings per lo mon
This commit is contained in:
168
chirp.cpp
168
chirp.cpp
@@ -13,8 +13,8 @@
|
||||
|
||||
#define MAX_CHANNELS 5
|
||||
|
||||
typedef void (*waveform_t)(const uint16_t, const uint32_t, uint8_t*);
|
||||
waveform_t waveforms[1];
|
||||
typedef void (*waveform_t)(const uint16_t, const uint32_t, uint8_t*, const uint8_t);
|
||||
static waveform_t waveforms[6];
|
||||
|
||||
const static uint16_t lengths[10] = { 313, 625, 938, 1250, 1875, 2500, 3750, 5000, 7500, 10000 };
|
||||
const static uint16_t tempos[10] = { 13230, 8820, 6615, 5292, 4410, 3780, 3308, 2940, 2646, 2406 };
|
||||
@@ -32,56 +32,59 @@ struct channel_t {
|
||||
uint32_t tempo = 44100;
|
||||
uint8_t waveform = 0;
|
||||
Uint8* play_pos;
|
||||
Uint32 play_len;
|
||||
int32_t play_len;
|
||||
Uint8 play_buffer[132300];
|
||||
};
|
||||
channel_t channels[MAX_CHANNELS];
|
||||
|
||||
static float default_length = 0.25f;
|
||||
static uint8_t volume = 32;
|
||||
static uint8_t octave = 4;
|
||||
static uint32_t tempo = 44100;
|
||||
static uint8_t waveform = 0;
|
||||
static char* song_ptr = NULL;
|
||||
static char* song = NULL;
|
||||
|
||||
static Uint8* play_pos;
|
||||
static Uint32 play_len;
|
||||
static Uint8 play_buffer[132300];
|
||||
static channel_t channels[MAX_CHANNELS];
|
||||
|
||||
void chirp_stop_channel(const int c) {
|
||||
if (channels[c].song != NULL) {
|
||||
free(channels[c].song);
|
||||
channels[c].song=NULL;
|
||||
}
|
||||
for (int i=0;i<MAX_CHANNELS;++i) if (channels[i].song != NULL) return;
|
||||
|
||||
audio_state=AUDIO_NONE;
|
||||
}
|
||||
|
||||
void audioCallback(void * userdata, uint8_t * stream, int len) {
|
||||
if (audio_state == AUDIO_PLAY) {
|
||||
while( len > 0 ) {
|
||||
while( play_len == 0 ) {
|
||||
play_len = interpret_next_token(play_buffer);
|
||||
if (play_len == -1) { audio_state=AUDIO_NONE; if (song != NULL) {free(song);song=NULL;}; SDL_memset( stream, 0, len ); return; }
|
||||
play_pos = play_buffer;
|
||||
}
|
||||
const int actual_len = ( len > play_len ? play_len : len );
|
||||
//SDL_memset( stream, 0, actual_len );
|
||||
//SDL_MixAudio( stream, audio_pos, actual_len, SDL_MIX_MAXVOLUME );
|
||||
SDL_memcpy(stream, play_pos, actual_len);
|
||||
|
||||
stream += actual_len;
|
||||
play_pos += actual_len;
|
||||
play_len -= actual_len;
|
||||
len -= actual_len;
|
||||
}
|
||||
} else {
|
||||
SDL_memset(stream, 0, len);
|
||||
if (audio_state == AUDIO_PLAY) {
|
||||
for (int i=0;i<MAX_CHANNELS;++i) if (channels[i].song != NULL) {
|
||||
int l_len=len;
|
||||
uint8_t *l_stream=stream;
|
||||
while( l_len > 0 ) {
|
||||
while( channels[i].play_len == 0 ) {
|
||||
channels[i].play_len = interpret_next_token(i);
|
||||
|
||||
if (channels[i].play_len == -1) {
|
||||
chirp_stop_channel(i);
|
||||
break;
|
||||
}
|
||||
channels[i].play_pos = channels[i].play_buffer;
|
||||
}
|
||||
if (channels[i].play_len == -1) break;
|
||||
|
||||
const int actual_len = ( l_len > channels[i].play_len ? channels[i].play_len : l_len );
|
||||
for (int j=0;j<actual_len;++j) l_stream[j] += channels[i].play_pos[j];
|
||||
|
||||
l_stream += actual_len;
|
||||
channels[i].play_pos += actual_len;
|
||||
channels[i].play_len -= actual_len;
|
||||
l_len -= actual_len;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void square_waveform(const uint16_t period, const uint32_t length, uint8_t *buffer) {
|
||||
for( int i = 0; i < length; i++ ) buffer[i] = ( (i % period) < (period >> 1) ? volume : -volume );
|
||||
void square_waveform(const uint16_t period, const uint32_t length, uint8_t *buffer, const uint8_t volume) {
|
||||
for( uint32_t i = 0; i < length; i++ ) buffer[i] = ( (i % period) < (period >> 1) ? volume : -volume );
|
||||
}
|
||||
void saw_waveform(const uint16_t period, const uint32_t length, uint8_t *buffer) {
|
||||
for( int i = 0; i < length; i++ ) buffer[i] = -volume + uint16_t( float(i % period) / float(period) * volume*2 );
|
||||
void saw_waveform(const uint16_t period, const uint32_t length, uint8_t *buffer, const uint8_t volume) {
|
||||
for( uint32_t i = 0; i < length; i++ ) buffer[i] = -volume + uint16_t( float(i % period) / float(period) * volume*2 );
|
||||
}
|
||||
void triangle_waveform(const uint16_t period, const uint32_t length, uint8_t *buffer) {
|
||||
for( int i = 0; i < length; i++ ) {
|
||||
void triangle_waveform(const uint16_t period, const uint32_t length, uint8_t *buffer, const uint8_t volume) {
|
||||
for( uint32_t i = 0; i < length; i++ ) {
|
||||
uint16_t pos = i % period;
|
||||
uint16_t half_period = period >> 1;
|
||||
if (pos < half_period) {
|
||||
@@ -91,14 +94,14 @@ void triangle_waveform(const uint16_t period, const uint32_t length, uint8_t *bu
|
||||
}
|
||||
}
|
||||
}
|
||||
void pulse12_waveform(const uint16_t period, const uint32_t length, uint8_t *buffer) {
|
||||
for( int i = 0; i < length; i++ ) buffer[i] = ( (i % period) < (period >> 3) ? volume : -volume );
|
||||
void pulse12_waveform(const uint16_t period, const uint32_t length, uint8_t *buffer, const uint8_t volume) {
|
||||
for( uint32_t i = 0; i < length; i++ ) buffer[i] = ( (i % period) < (period >> 3) ? volume : -volume );
|
||||
}
|
||||
void pulse25_waveform(const uint16_t period, const uint32_t length, uint8_t *buffer) {
|
||||
for( int i = 0; i < length; i++ ) buffer[i] = ( (i % period) < (period >> 2) ? volume : -volume );
|
||||
void pulse25_waveform(const uint16_t period, const uint32_t length, uint8_t *buffer, const uint8_t volume) {
|
||||
for( uint32_t i = 0; i < length; i++ ) buffer[i] = ( (i % period) < (period >> 2) ? volume : -volume );
|
||||
}
|
||||
void pulse75_waveform(const uint16_t period, const uint32_t length, uint8_t *buffer) {
|
||||
for( int i = 0; i < length; i++ ) buffer[i] = ( (i % period) < (period-(period >> 2)) ? volume : -volume );
|
||||
void pulse75_waveform(const uint16_t period, const uint32_t length, uint8_t *buffer, const uint8_t volume) {
|
||||
for( uint32_t i = 0; i < length; i++ ) buffer[i] = ( (i % period) < uint16_t(period-(period >> 2)) ? volume : -volume );
|
||||
}
|
||||
|
||||
void chirp_init() {
|
||||
@@ -111,35 +114,42 @@ void chirp_init() {
|
||||
waveforms[3] = &pulse12_waveform;
|
||||
waveforms[4] = &pulse25_waveform;
|
||||
waveforms[5] = &pulse75_waveform;
|
||||
for (uint8_t i=0;i<MAX_CHANNELS;++i) channels[i].song=NULL;
|
||||
}
|
||||
|
||||
uint32_t interpret_note(uint8_t* buffer, const char note, const char param ) {
|
||||
const uint32_t length = ( param == -1 ? default_length : ((float)lengths[param])/10000.0f ) * tempo;
|
||||
if( note == SILENCE ) { memset( buffer, 0, length ); return length; }
|
||||
if( note == NOISE ) { for( int i = 0; i < length; i++ ) buffer[i] = rand()%2==0 ? volume : -volume; return length; }
|
||||
uint32_t interpret_note(const int c, const char note, const char param ) {
|
||||
const uint32_t length = ( param == -1 ? channels[c].length : ((float)lengths[uint8_t(param)])/10000.0f ) * channels[c].tempo;
|
||||
if( note == SILENCE ) { memset( channels[c].play_buffer, 0, length ); return length; }
|
||||
if( note == NOISE ) { for( uint32_t i = 0; i < length; i++ ) channels[c].play_buffer[i] = rand()%2==0 ? channels[c].volume : -channels[c].volume; return length; }
|
||||
|
||||
const uint16_t period = periods[note + octave*12];
|
||||
waveforms[waveform](period, length, buffer);
|
||||
const uint16_t period = periods[note + channels[c].octave*12];
|
||||
waveforms[channels[c].waveform](period, length, channels[c].play_buffer, channels[c].volume);
|
||||
return length;
|
||||
}
|
||||
|
||||
void chirp_play(const char* new_song) {
|
||||
play_pos = play_buffer;
|
||||
play_len = 0;
|
||||
int chirp_play(const char* new_song) {
|
||||
int c = 0;
|
||||
while (c<MAX_CHANNELS && channels[c].song != NULL) c++;
|
||||
if (c==MAX_CHANNELS) return -1;
|
||||
|
||||
volume=32;
|
||||
octave=4;
|
||||
tempo=44100;
|
||||
if (song != NULL) free(song);
|
||||
song = (char*)malloc( strlen( new_song ) + 1 );
|
||||
strcpy( song, new_song );
|
||||
song_ptr = song;
|
||||
channels[c].play_pos = channels[c].play_buffer;
|
||||
channels[c].play_len = 0;
|
||||
|
||||
channels[c].length=0.25f;
|
||||
channels[c].volume=32;
|
||||
channels[c].octave=4;
|
||||
channels[c].tempo=44100;
|
||||
channels[c].waveform=0;
|
||||
channels[c].song = (char*)malloc( strlen( new_song ) + 1 );
|
||||
strcpy( channels[c].song, new_song );
|
||||
channels[c].song_ptr = channels[c].song;
|
||||
|
||||
audio_state = AUDIO_PLAY;
|
||||
return c;
|
||||
}
|
||||
|
||||
int32_t interpret_next_token(uint8_t* buffer) {
|
||||
char** token = &song_ptr;
|
||||
int32_t interpret_next_token(const int c) { //uint8_t* buffer) {
|
||||
char** token = &channels[c].song_ptr;
|
||||
char note = 0;
|
||||
char param = -1;
|
||||
|
||||
@@ -154,43 +164,43 @@ int32_t interpret_next_token(uint8_t* buffer) {
|
||||
param = *++*token;
|
||||
if( param == '#' || param == '+' ) { note++; param = *++*token; } else if( param == '-' ) { note--; param = *++*token; }
|
||||
if( param >= 48 && param <= 57 ) { param -= 48; ++*token; } else { param = -1; }
|
||||
return interpret_note( buffer, note, param );
|
||||
return interpret_note( c, note, param );
|
||||
case 'r':
|
||||
param = *++*token;
|
||||
if( param >= 48 && param <= 57 ) { param -= 48; ++*token; } else { param = -1; }
|
||||
return interpret_note( buffer, SILENCE, param );
|
||||
return interpret_note( c, SILENCE, param );
|
||||
case 'n':
|
||||
param = *++*token;
|
||||
if( param >= 48 && param <= 57 ) { param -= 48; ++*token; } else { param = -1; }
|
||||
return interpret_note( buffer, NOISE, param );
|
||||
return interpret_note( c, NOISE, param );
|
||||
case 'o':
|
||||
param = *++*token;
|
||||
if( param >= 48 && param <= 57 ) { octave = (param - 48) % 8; ++*token; }
|
||||
if( param >= 48 && param <= 57 ) { channels[c].octave = (param - 48) % 8; ++*token; }
|
||||
return 0;
|
||||
case '>':
|
||||
octave = (octave+1) % 8; ++*token;
|
||||
channels[c].octave = (channels[c].octave+1) % 8; ++*token;
|
||||
return 0;
|
||||
case '<':
|
||||
octave = (octave-1) % 8; ++*token;
|
||||
channels[c].octave = (channels[c].octave-1) % 8; ++*token;
|
||||
return 0;
|
||||
case 'l':
|
||||
param = *++*token;
|
||||
if( param >= 48 && param <= 57 ) { default_length = ((float)lengths[param - 48])/10000.0f; ++*token; }
|
||||
if( param >= 48 && param <= 57 ) { channels[c].length = ((float)lengths[param - 48])/10000.0f; ++*token; }
|
||||
return 0;
|
||||
case 'v':
|
||||
param = *++*token;
|
||||
if( param >= 48 && param <= 57 ) { volume = (param - 48) << 3; ++*token; }
|
||||
if( param >= 48 && param <= 57 ) { channels[c].volume = (param - 48) << 3; ++*token; }
|
||||
return 0;
|
||||
case 't':
|
||||
param = *++*token;
|
||||
if( param >= 48 && param <= 57 ) { tempo = tempos[param - 48] * 10; ++*token; }
|
||||
if( param >= 48 && param <= 57 ) { channels[c].tempo = tempos[param - 48] * 10; ++*token; }
|
||||
return 0;
|
||||
case 'w':
|
||||
param = *++*token;
|
||||
if( param >= 48 && param <= 57 ) { waveform = param - 48; ++*token; }
|
||||
if( param >= 48 && param <= 57 ) { channels[c].waveform = param - 48; ++*token; }
|
||||
return 0;
|
||||
case '=':
|
||||
song_ptr = song;
|
||||
channels[c].song_ptr = channels[c].song;
|
||||
return 0;
|
||||
case '\0':
|
||||
return -1;
|
||||
@@ -201,9 +211,11 @@ int32_t interpret_next_token(uint8_t* buffer) {
|
||||
}
|
||||
|
||||
void chirp_stop() {
|
||||
if (song != NULL) {
|
||||
free(song);
|
||||
song=NULL;
|
||||
for (int i=0;i<MAX_CHANNELS;++i) {
|
||||
if (channels[i].song != NULL) {
|
||||
free(channels[i].song);
|
||||
channels[i].song=NULL;
|
||||
}
|
||||
}
|
||||
audio_state=AUDIO_NONE;
|
||||
}
|
||||
|
||||
4
chirp.h
4
chirp.h
@@ -3,8 +3,8 @@
|
||||
|
||||
void chirp_init();
|
||||
|
||||
void chirp_play(const char* new_song, const bool lock);
|
||||
int chirp_play(const char* new_song);
|
||||
|
||||
int32_t interpret_next_token(uint8_t* buffer);
|
||||
int32_t interpret_next_token(const int c);
|
||||
|
||||
void chirp_stop();
|
||||
|
||||
@@ -2,7 +2,8 @@ x=0
|
||||
|
||||
function _init()
|
||||
text="HOLA MINI"
|
||||
playchirp("o4w4cdw5cd")
|
||||
playchirp("o4w4ce")
|
||||
playchirp("o4w4go5c")
|
||||
end
|
||||
|
||||
function _update()
|
||||
|
||||
60
gif.c
60
gif.c
@@ -295,7 +295,6 @@ unsigned char* process_image_descriptor( unsigned char* buffer,
|
||||
int resolution_bits )
|
||||
{
|
||||
image_descriptor_t image_descriptor;
|
||||
int disposition;
|
||||
int compressed_data_length;
|
||||
unsigned char *compressed_data = NULL;
|
||||
unsigned char lzw_code_size;
|
||||
@@ -307,8 +306,6 @@ unsigned char* process_image_descriptor( unsigned char* buffer,
|
||||
|
||||
// TODO if LCT = true, read the LCT
|
||||
|
||||
disposition = 1;
|
||||
|
||||
READ(&lzw_code_size, 1);
|
||||
|
||||
compressed_data_length = read_sub_blocks( buffer, &compressed_data );
|
||||
@@ -330,59 +327,6 @@ unsigned char* process_image_descriptor( unsigned char* buffer,
|
||||
return uncompressed_data;
|
||||
}
|
||||
|
||||
static int process_extension( unsigned char* buffer )
|
||||
{
|
||||
/*extension_t extension;
|
||||
graphic_control_extension_t gce;
|
||||
application_extension_t application;
|
||||
plaintext_extension_t plaintext;
|
||||
unsigned char *extension_data = NULL;
|
||||
int extension_data_length;*/
|
||||
|
||||
|
||||
/* switch ( extension.extension_code )
|
||||
{
|
||||
case GRAPHIC_CONTROL:
|
||||
READ(&gce, 4);
|
||||
|
||||
break;
|
||||
case APPLICATION_EXTENSION:
|
||||
READ(&application, extension.block_size);
|
||||
break;
|
||||
case 0xFE:
|
||||
// comment extension; do nothing - all the data is in the
|
||||
// sub-blocks that follow.
|
||||
break;
|
||||
case 0x01:
|
||||
READ(&plaintext, 12);
|
||||
break;
|
||||
default:
|
||||
fprintf( stderr, "Unrecognized extension code.\n" );
|
||||
exit( 0 );
|
||||
}*/
|
||||
|
||||
unsigned char extension, size;
|
||||
READ(&extension, 1);
|
||||
READ(&size, 1);
|
||||
buffer += size;
|
||||
|
||||
unsigned char block_size;
|
||||
do {
|
||||
READ(&block_size, 1);
|
||||
buffer += block_size;
|
||||
} while (block_size != 0);
|
||||
|
||||
/*
|
||||
// All extensions are followed by data sub-blocks; even if it's
|
||||
// just a single data sub-block of length 0
|
||||
extension_data_length = read_sub_blocks( buffer, &extension_data );
|
||||
|
||||
if ( extension_data != NULL )
|
||||
free( extension_data );
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param gif_file the file descriptor of a file containing a
|
||||
* GIF-encoded file. This should point to the first byte in
|
||||
@@ -393,7 +337,7 @@ static int process_extension( unsigned char* buffer )
|
||||
uint32_t* LoadPalette(unsigned char *buffer) {
|
||||
unsigned char header[7];
|
||||
screen_descriptor_t screen_descriptor;
|
||||
int color_resolution_bits;
|
||||
//int color_resolution_bits;
|
||||
|
||||
int global_color_table_size = 0; // number of entries in global_color_table
|
||||
uint32_t *global_color_table = NULL;
|
||||
@@ -401,7 +345,7 @@ uint32_t* LoadPalette(unsigned char *buffer) {
|
||||
READ(header, 6);
|
||||
READ(&screen_descriptor, 7);
|
||||
|
||||
color_resolution_bits = ((screen_descriptor.fields & 0x70) >> 4) + 1;
|
||||
//color_resolution_bits = ((screen_descriptor.fields & 0x70) >> 4) + 1;
|
||||
global_color_table = (uint32_t *)calloc(1, 1024);
|
||||
|
||||
if (screen_descriptor.fields & 0x80) {
|
||||
|
||||
@@ -86,7 +86,7 @@ FILE *file_getfilepointer(const char *resourcename, int& filesize, const bool bi
|
||||
|
||||
if (file_source==SOURCE_FILE) {
|
||||
bool found = false;
|
||||
int count = 0;
|
||||
uint32_t count = 0;
|
||||
while( !found && count < data_file->header.num_files ) {
|
||||
found = ( strcmp( resourcename, data_file->index.file_info[count].name ) == 0 );
|
||||
if( !found ) count++;
|
||||
|
||||
4
lua.cpp
4
lua.cpp
@@ -651,9 +651,7 @@ extern "C" {
|
||||
|
||||
static int cpp_playchirp(lua_State *L) {
|
||||
const char* str = luaL_checkstring(L, 1);
|
||||
bool value = false;
|
||||
if (lua_gettop(L) > 1) value = lua_toboolean(L, 2);
|
||||
playchirp(str, value);
|
||||
playchirp(str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
13
mini.cpp
13
mini.cpp
@@ -186,7 +186,7 @@ int main(int argc,char*argv[]){
|
||||
// initfont()
|
||||
int bi = 0;
|
||||
for (int ci=0; ci<96; ci+=2) {
|
||||
font[ci] = base64font[bi]-48+((base64font[bi+1]-48)<<6)+((base64font[bi+2]-48&7)<<12);
|
||||
font[ci] = base64font[bi] - 48 + ( ( base64font[bi+1] - 48 ) << 6) + ( ( ( base64font[bi+2] - 48 ) & 7 ) << 12 );
|
||||
font[ci+1] = ( ( base64font[bi+2] - 48 ) >> 3 ) + ( ( base64font[bi+3] - 48 ) << 3 ) + ( ( base64font[bi+4] - 48 ) << 9 );
|
||||
bi += 5;
|
||||
}
|
||||
@@ -255,7 +255,7 @@ int main(int argc,char*argv[]){
|
||||
key_just_pressed = 0;
|
||||
}
|
||||
SDL_LockTexture(mini_bak, NULL, (void**)&pixels, &pitch);
|
||||
for (int i=0;i<screen_surface->size;++i) pixels[i] = palette[screen_surface->p[i]];
|
||||
for (uint32_t i=0;i<screen_surface->size;++i) pixels[i] = palette[screen_surface->p[i]];
|
||||
SDL_UnlockTexture(mini_bak);
|
||||
SDL_RenderCopy(mini_ren, mini_bak, NULL, NULL);
|
||||
SDL_RenderPresent(mini_ren);
|
||||
@@ -512,7 +512,7 @@ const char t195_symbol[]={1,2,0,0,0,0,0,3,1,2,0,0,1,2,0,0,0,4,1,2,0,0,0,0,0,1,2,
|
||||
|
||||
void print(const char *str, int x, int y) {
|
||||
int pos=0;
|
||||
for (int i=0; i < SDL_strlen(str); ++i) {
|
||||
for (size_t i=0; i < SDL_strlen(str); ++i) {
|
||||
if ((unsigned char)str[i]==194) {
|
||||
i++;
|
||||
if ((unsigned char)str[i]==161) print_char_hv('!', x+pos*4, y);
|
||||
@@ -678,7 +678,8 @@ void spr(uint8_t n, int x, int y, float w, float h, bool flip_x, bool flip_y) {
|
||||
}
|
||||
|
||||
void sspr(int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, bool flip_x, bool flip_y) {
|
||||
if (dw==0)dw=sw; if (dh==0)dh=sh;
|
||||
if (dw==0) dw=sw;
|
||||
if (dh==0) dh=sh;
|
||||
float sdx = float(sw)/float(dw);
|
||||
float sdy = float(sh)/float(dh);
|
||||
float ssx = sx; float ssy = sy;
|
||||
@@ -986,8 +987,8 @@ bool freadb() {
|
||||
return strcmp(fstr, "true")==0?true:false;
|
||||
}
|
||||
|
||||
void playchirp(const char *song, const bool lock) {
|
||||
chirp_play(song, lock);
|
||||
void playchirp(const char *song) {
|
||||
chirp_play(song);
|
||||
}
|
||||
|
||||
void stopchirp() {
|
||||
|
||||
Reference in New Issue
Block a user