From: slack Date: Sat, 29 Aug 2009 20:01:31 +0000 (+0200) Subject: Initial commit X-Git-Url: http://slack.codemaniacs.com/git/?a=commitdiff_plain;h=4bd262e766a930b2e878acfd4dfc006827c11d21;p=fov120.git Initial commit --- 4bd262e766a930b2e878acfd4dfc006827c11d21 diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..13e9174 --- /dev/null +++ b/Makefile @@ -0,0 +1,29 @@ +#CC=/home/slack/temp/gcc4/bin/gcc +CFLAGS=-m32 -Os -std=c99 -fomit-frame-pointer -ffast-math -Wall -DX86_ASM \ + $(shell sdl-config --cflags) -fno-strict-aliasing #-DDEBUG + +LDFLAGS=-m32 -nostdlib -nostartfiles -ldl -lpthread -lm + +all: main + ./pack.sh main + +main: main.o dl_init.o + $(CC) $(LDFLAGS) -o $@ $^ + ls -l main + +synth.o: synth.c synth.h + $(CC) $(CFLAGS) -c -o $@ $< + +main.o: main.c play.c + $(CC) $(CFLAGS) -c -o $@ $< + +dl_init.o: dl_init.c dl_init.h + $(CC) $(CFLAGS) -c -o $@ $< + #nasm -O9 -f elf -o $@ $< + + +clean: + rm -f *.o main intro intro.gz *~ + +.PHONY: clean + diff --git a/dl_init.c b/dl_init.c new file mode 100644 index 0000000..79ddf34 --- /dev/null +++ b/dl_init.c @@ -0,0 +1,55 @@ +#include "dl_init.h" +#include + +FN_STRUCT fn; + +char *names="libSDL-1.2.so.0\0SDL_Init\0SDL_Quit\0SDL_OpenAudio\0" + "SDL_PauseAudio\0SDL_SetVideoMode\0SDL_PollEvent\0" + "SDL_GL_SetAttribute\0SDL_GL_SwapBuffers\0SDL_GetTicks\0" + "SDL_ShowCursor\0" + + "libm.so\0powf\0fmodf\0"//expf\0" + + "libc.so.6\0rand\0srand\0time\0" + + "libGL.so\0glBegin\0glEnd\0glColor4f\0glVertex3fv\0glRotatef\0" + "glEnable\0glMatrixMode\0glLoadIdentity\0glClear\0" + "glBlendFunc\0glTranslatef\0glPushMatrix\0glPopMatrix\0glRectf\0" + "glClearColor\0glXUseXFont\0glRasterPos2f\0glCallLists\0" + + "libGLU.so\0gluPerspective\0gluLookAt\0" + + "libX11.so\0XOpenDisplay\0XLoadQueryFont\0" + + "\0"; + + +void dl_init(void) +{ + char *p=names; + void **pfn=(void **)&fn; + void *handle, *tmp; + + while(*p) + { + tmp = dlopen(p, RTLD_LAZY); + if (tmp == NULL) + { + *pfn=dlsym(handle, p); + #ifdef DEBUG + __builtin_printf("%s = %p\n", p, *pfn); + #endif + ++pfn; + } + else + { + handle=tmp; + #ifdef DEBUG + __builtin_printf("%s = %p\n", p, handle); + #endif + } + while(*p++); // Avanzamos p hasta la siguiente + } +} + + diff --git a/dl_init.h b/dl_init.h new file mode 100644 index 0000000..d407485 --- /dev/null +++ b/dl_init.h @@ -0,0 +1,80 @@ +#ifndef DL_INIT_H +#define DL_INIT_H + +#include "SDL.h" +#include +#include + +typedef struct +{ + // libSDL + int (*SDL_Init)(Uint32); + void (*SDL_Quit)(void); + int (*SDL_OpenAudio)(SDL_AudioSpec*, SDL_AudioSpec*); + + //void (*SDL_CloseAudio)(void); + void (*SDL_PauseAudio)(int); + SDL_Surface *(*SDL_SetVideoMode)(int, int, int, Uint32); + int (*SDL_PollEvent)(SDL_Event*); + int (*SDL_GL_SetAttribute)(SDL_GLattr, int); + void (*SDL_GL_SwapBuffers)(void); + Uint32 (*SDL_GetTicks)(); + int (*SDL_ShowCursor)(int); + + // libm + float (*powf)(float, float); + float (*fmodf)(float, float); + //float (*expf)(float); + + // libc + int (*rand)(void); + void (*srand)(unsigned int); + time_t (*time)(time_t*); + + // libGL + void (*glBegin)(GLenum); + void (*glEnd)(void); + void (*glColor4f)(GLfloat, GLfloat, GLfloat, GLfloat); + //void (*glVertex3f)(GLfloat, GLfloat, GLfloat); + void (*glVertex3fv)(const GLfloat*); + void (*glRotatef)(GLfloat, GLfloat, GLfloat, GLfloat); + void (*glEnable)(GLenum); + //void (*glDisable)(GLenum); + void (*glMatrixMode)(GLenum); + void (*glLoadIdentity)(void); + void (*glClear)(GLbitfield); + //void (*glScalef)(GLfloat, GLfloat, GLfloat); + void (*glBlendFunc)(GLenum, GLenum); + void (*glTranslatef)(GLfloat, GLfloat, GLfloat); + //void (*glNormal3f)(GLfloat, GLfloat, GLfloat); + //void (*glTexGeni)(GLenum, GLenum, GLint); + //void (*glGetFloatv)(GLenum, GLfloat *); + void (*glPushMatrix)(void); + void (*glPopMatrix)(void); + //void (*glTexCoord2f)(GLfloat, GLfloat); + //void (*glBindTexture)(GLenum, GLuint); + //void (*glGenTextures)(GLsizei, GLuint *); + void (*glRectf)(GLfloat, GLfloat, GLfloat, GLfloat); + void (*glClearColor)(GLfloat, GLfloat, GLfloat, GLfloat); + void (*glXUseXFont)(Font, int, int, int); + void (*glRasterPos2f)(GLfloat, GLfloat); + void (*glCallLists)(GLsizei, GLenum, const GLvoid *); + + // libGLU + void (*gluPerspective)(GLdouble, GLdouble, GLdouble, GLdouble); + void (*gluLookAt)(GLdouble, GLdouble, GLdouble, + GLdouble, GLdouble, GLdouble, + GLdouble, GLdouble, GLdouble); + //GLint (*gluBuild2DMipmaps)(GLenum, GLint, GLsizei, GLsizei, + // GLenum, GLenum, const void *); + + // libX11.so + Display* (*XOpenDisplay)(int); + XFontStruct* (*XLoadQueryFont)(Display*, char *); + +} FN_STRUCT; + +extern void dl_init(void); +extern FN_STRUCT fn; + +#endif//DL_INIT_H diff --git a/floatfucker.py b/floatfucker.py new file mode 100755 index 0000000..885a9c2 --- /dev/null +++ b/floatfucker.py @@ -0,0 +1,26 @@ +#!/usr/bin/python +# floatfucker.py by slack/Necrostudios +# it now rounds instead of truncating (thanks iq :) + +import re +import sys +from struct import pack, unpack + +def trunc_float(f): + return unpack("f",pack("I", (unpack("I",pack("f",f))[0]+0x8000)&0xFFFF0000))[0] + +def repl_float(m): + s = m.group() + try: + f = float(s[:-1]) + except: + print "ERROR ----> ", s + return s + f2 = trunc_float(f) + return str(f2)+"f" + +float_re = re.compile("(([+-]|)\d*\.\d+|\d+\.\d*)f", re.I) + +src = file(sys.argv[1]).read() +dst = float_re.sub(repl_float, src) +file(sys.argv[2],"w").write(dst) diff --git a/gz-stub b/gz-stub new file mode 100644 index 0000000..baf34c0 --- /dev/null +++ b/gz-stub @@ -0,0 +1,6 @@ +a=/tmp/a +tail -n+7 $0|zcat>$a +chmod +x $a +$a +rm $a +exit diff --git a/main.c b/main.c new file mode 100644 index 0000000..74711c8 --- /dev/null +++ b/main.c @@ -0,0 +1,52 @@ +#include +#include +#include + +#include "dl_init.h" + +//#define sin(x) __builtin_sinf(x) +//#define cos(x) __builtin_cosf(x) +//#define sqrt(x) __builtin_sqrtf(x) +//#define expf(x) __builtin_expf(x) + +float current_t; + +#ifdef DEBUG +int main() +#else +void __attribute__((externally_visible)) _start(void) +#endif +{ + SDL_Event event; + dl_init(); + + fn.SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO); + fn.SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1); + fn.SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL,1); + fn.SDL_SetVideoMode(1280,960,32,SDL_OPENGL); + fn.SDL_ShowCursor(0); + + while(1) + { + current_t = fn.SDL_GetTicks()/1000.0f; + while(fn.SDL_PollEvent(&event)) + { + if (event.type == SDL_KEYDOWN) + goto end; + } + + fn.SDL_GL_SwapBuffers(); + } + +end: + fn.SDL_Quit(); + +#if 1 + __asm__("xorl %eax, %eax\n\t" + "incl %eax\n\t" + "int $0x80\n\t"); +#else + exit(0); +#endif +} + diff --git a/pack.sh b/pack.sh new file mode 100755 index 0000000..be9d844 --- /dev/null +++ b/pack.sh @@ -0,0 +1,7 @@ +./sstrip $1 +#cp gz-stub intro +#gzip -c9 $1 >> intro +7z a -tGZIP -mx=9 -mfb=64 intro.gz $1 +cat gz-stub intro.gz > intro +chmod +x intro +ls -l intro diff --git a/play.c b/play.c new file mode 100644 index 0000000..d5a0d9b --- /dev/null +++ b/play.c @@ -0,0 +1,229 @@ +#include "SDL.h" +#include "dl_init.h" +#include "synth.h" +#include "play.h" +#include "song.h" + +#define msin(x) __builtin_sinf(x) +#define mcos(x) __builtin_cosf(x) +#define mfmodf(x,y) fn.fmodf(x,y) + +#ifdef OUTFILE +#include +FILE *fout; +#endif + +#define NUM_VOICES 64 + +Voice voices[NUM_RHYTHM_CHANNELS+NUM_VOICES]={{0}}; +float mix_buf[BUFFER_SIZE]={0}; +unsigned int last_voice_used=0; +int buf_start; + +float current_time=0; +int rhythm_offset; +float global_vol=1.0f; +int music_ticks=-1; + + +float cam_rotation, cam_rotation0, cam_rot_x, cam_rot_y, cam_rot_z; +float tri_z_spread=8.0f; + +int negative_bars=0; + +enum params{ + FOV=0, + TRI_Z_SPREAD, + TRI_SPEED, + CAMERA_POS, + NEGATIVE, + NUM_PARAMS, +}; + +typedef struct +{ + float x, y, z, w, x1, y1, z1, w1, x0, y0, z0, w0, scale, offset, trans_start, trans_end; +} Param; + + +Param params[NUM_PARAMS]; + +extern void update_params(); + +void change_param(int which) +{ + if (which < 0) + which = rand_4k()%NUM_PARAMS; + params[which].x0 = params[which].x; + params[which].y0 = params[which].y; + params[which].z0 = params[which].z; + params[which].x1 = sfrand() * params[which].scale + params[which].offset; + params[which].y1 = sfrand() * params[which].scale + params[which].offset; + params[which].z1 = sfrand() * params[which].scale + params[which].offset; + params[which].trans_start = current_time; + params[which].trans_end = current_time + sfrand()*2.0f+2.0f; // entre 1 y 5 +} + + +static void note_on(int note, float vol, int instrument) +{ + if (rand()%10) + { + int j = last_voice_used + NUM_RHYTHM_CHANNELS; + last_voice_used = (last_voice_used + 1) % NUM_VOICES; + voices[j].pitch = 440.0f*detune(note-45,0); + voices[j].pos = buf_start; + voices[j].ins = instrument; + voices[j].vol = global_vol*0.19921875f*vol; + voices[j].active = 1; + } +} + +enum chords_enum { + MAJOR=0, + MINOR, + MAJOR_SEVENTH, + MINOR_SEVENTH, + NUM_CHORDS, +}; + +enum scales_enum { + MAJOR_SCALE=0, + MINOR_SCALE, + NUM_SCALES, +}; + +int chords[4*NUM_CHORDS] = { + 0,4,7,-1, + 0,3,7,-1, + 0,4,7,11, + 0,3,7,11, +}; + +int scales[7*NUM_SCALES] = { + 0,2,4,5,7,9,11, + 0,2,3,5,7,8,10, +}; + +static void chord_on(int base, int type, float vol, int instrument) +{ + note_on(base+chords[4*type], vol, instrument); + note_on(base+chords[4*type+1], vol, instrument); + note_on(base+chords[4*type+2], vol, instrument); + if (chords[4*type+3] >= 0) + note_on(base+chords[4*type+3], vol, instrument); +} + +int current_chord_base, current_chord_type; +int bass_arpeggio[3]={0,1,2}; + +// Main audio callback +static void play(Song *s, Uint8 *stream, int len) +{ + unsigned int i; + unsigned int num_samples=len>>1; + float tmp; + Sint16 *buf=(Sint16 *)stream; + + current_time += num_samples/SAMPLE_RATE; + +#ifdef X86_ASM + __asm__("rep; stosl;"::"a"(0), "c"(BUFFER_SIZE), "D"(mix_buf)); +#else + __builtin_memset(mix_buf, 0, BUFFER_SIZE*sizeof(float)); +#endif + + + if ((current_time - music_ticks * ROW_DURATION) > ROW_DURATION ) + { + ++music_ticks; + buf_start = ((current_time - music_ticks * ROW_DURATION)*SAMPLE_RATE)-num_samples; + + + // Cambio de acorde cada 4 compases + if (music_ticks%32 == 0) + { + current_chord_base=rand()%12+16; + current_chord_type=rand()%2; + change_param(-1); + } + + if (music_ticks%8 == 0) + { + int i1=rand()%3; + int i2=rand()%3; + int tmp = bass_arpeggio[i1]; + bass_arpeggio[i1] = bass_arpeggio[i2]; + bass_arpeggio[i2] = tmp; + + if (--negative_bars < 0) + { + negative_bars = rand_4k()%32+8; + params[NEGATIVE].x0 = params[NEGATIVE].x1; + if (params[NEGATIVE].x1 == 0.0f) + params[NEGATIVE].x1=1.0f; + else + params[NEGATIVE].x1=0.0f; + params[NEGATIVE].trans_start = current_time; + params[NEGATIVE].trans_end = current_time + 2.0f; // entre 1 y 5 + } + } + + if (music_ticks%16 == 0) + chord_on(current_chord_base, current_chord_type, 0.2f, 1); + + if (music_ticks%2 == 0) + { + float vol = 1.0f-((music_ticks%8)/8.0f); + chord_on(current_chord_base, current_chord_type, vol, 3); + + } + + if (music_ticks%2 == 0) + { + note_on(current_chord_base+12+chords[4*current_chord_type+rand()%3], 1.0f, 4); + note_on(current_chord_base-12+chords[4*current_chord_type+bass_arpeggio[(music_ticks%6)/2]], 1.0f,2); + } + else + { + if (rand() % 2 == 0) + note_on(current_chord_base+12+scales[4*current_chord_type%2+rand()%7], 0.5f, 4); + + if (rand() % 4 == 0) + note_on(current_chord_base-12+scales[4*current_chord_type%2+(music_ticks%6)], 0.5f,2); + } + } + + // Ahora vamos sintetizando las voces + for (i=0; i < NUM_VOICES + NUM_RHYTHM_CHANNELS; ++i) + { + if (voices[i].active) + { + voices[i].active=synth(&voices[i], num_samples, mix_buf); + } + } + + // convertimos a Sint16 + for (i=0; i1.0f) tmp=1.0f; + else if(tmp<-1.0f) tmp=-1.0f; + buf[i]=(Sint16)(tmp*32640.0f); + } + +#ifdef OUTFILE + fwrite(buf, sizeof(Sint16), num_samples, fout); +#endif + +} + +SDL_AudioSpec desired={44100, + AUDIO_S16SYS, + 1, + 0, + BUFFER_SIZE, + 0, + 0, + (void (*)(void *, Uint8 *, int)) play, + 0}; diff --git a/play.h b/play.h new file mode 100644 index 0000000..60c5eff --- /dev/null +++ b/play.h @@ -0,0 +1,27 @@ +#ifndef _TRACK_H_ +#define _TRACK_H_ + +#include "SDL.h" +#include "synth.h" + +#define NUM_PATTERNS 300 +#define NUM_ENVELOPES 4 +#define NUM_INSTRUMENTS 300 +#define NUM_RHYTHM_CHANNELS 10 +#define NUM_CHANNELS 50 +#define TRACK_LENGTH 16 + +//#define OUTFILE "salida.raw" + +typedef struct _Song +{ + //float row_duration; // in seconds + Envelope envelopes[NUM_ENVELOPES]; + Instrument insts[NUM_INSTRUMENTS]; +} Song; + +#define sfrand() (2.0f*whitenoise()-1.0f) + +#endif + + diff --git a/song.h b/song.h new file mode 100644 index 0000000..c19021e --- /dev/null +++ b/song.h @@ -0,0 +1,80 @@ +#ifndef SONG_H +#define SONG_H + +#define ROW_DURATION 0.27 + +Song song={ + //Envelopes + { + {0,0,0,0,0}, // env nr 0 = special case (no envelope) + {20,120,40,200,20}, + {0,5,30,30,0}, + {0,20,15,30,0}, + }, + // Instruments + { + // Ins 0 (bass drum) + { + 0.0f, // cutoff + 0.0f, // lfo_amp + 0, // lfo_freq + 0, // res + 0,0, + 0,0, // detune + 0,0, + 0, + 0, 0, + }, + // Ins 1 (hihat) + { + -4000.0f, + 500.0f, + 5, + 100, + 24,1, + 36,-1, + 70,80, + 0, + 1,0, + }, + // Ins 2 (bass) + { + 700.0f, // cutoff + -400.0f, // lfo_amp + -1, // lfo_freq + 15, // res + 12,1, + 12,0, // detune + 70,70, // vols + 10, //noise + 2, 0, + }, + // Ins 3 ("sin" con attack) + { + 800.0f, // cutoff + 300.0f, // lfo_amp + 2, // lfo_freq + 30, // res + 12,1, + 12,0, // detune + 40,60, // vols + 0, //noise + 3, 0, + }, + // Ins 4 (lead) + { + 1848.0f, // cutoff + 500.0f, // lfo_amp + 80, // lfo_freq + 15, // res + 24,1, + 12,0, // detune + 40,50, // vols + 0, //noise + 2, 0, + }, + }, +}; + +#endif + diff --git a/sstrip b/sstrip new file mode 100755 index 0000000..d51aabe Binary files /dev/null and b/sstrip differ diff --git a/sstrip.c b/sstrip.c new file mode 100644 index 0000000..60128e6 --- /dev/null +++ b/sstrip.c @@ -0,0 +1,332 @@ + +/* sstrip, version 2.0: Copyright (C) 1999-2001 by Brian Raiter, under the + * GNU General Public License. No warranty. See LICENSE for details. + */ + +/* #include "config_xor.h" */ + +#include +#include +#include +#include +#include +#include + +#if !defined(__ia64) && !defined(__ia64__) && !defined(__itanium__) && \ + !defined(__alpha) && !defined(__alpha__) && \ + (defined(__linux__) || defined(__FreeBSD__)) && \ + (defined(__i386__) || defined(__i386) || defined(i386)) + +/* || defined(__sun) || defined(__sun__) || defined(sun) */ + +#if defined(__linux__) +#include +#else +#include +#endif + +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif + +#if ELF_CLASS == ELFCLASS32 +#define Elf_Ehdr Elf32_Ehdr +#define Elf_Phdr Elf32_Phdr +#else +#define Elf_Ehdr Elf64_Ehdr +#define Elf_Phdr Elf64_Phdr +#endif + +/* The name of the program. + */ +static char const *progname; + +/* The name of the current file. + */ +static char const *filename; + + +/* A simple error-handling function. FALSE is always returned for the + * convenience of the caller. + */ +static int err(char const *errmsg) +{ + fprintf(stderr, "%s: %s: %s\n", progname, filename, errmsg); + return FALSE; +} + +/* A macro for I/O errors: The given error message is used only when + * errno is not set. + */ +#define ferr(msg) (err(errno ? strerror(errno) : (msg))) + +/* readelfheader() reads the ELF header into our global variable, and + * checks to make sure that this is in fact a file that we should be + * munging. + */ +static int readelfheader(int fd, Elf_Ehdr *ehdr) +{ + errno = 0; + if (read(fd, ehdr, sizeof *ehdr) != sizeof *ehdr) + return ferr("missing or incomplete ELF header."); + + /* Check the ELF signature. + */ + if (!(ehdr->e_ident[EI_MAG0] == ELFMAG0 && + ehdr->e_ident[EI_MAG1] == ELFMAG1 && + ehdr->e_ident[EI_MAG2] == ELFMAG2 && + ehdr->e_ident[EI_MAG3] == ELFMAG3)) + return err("missing ELF signature."); + + /* Compare the file's class and endianness with the program's. + */ + if (ehdr->e_ident[EI_DATA] != ELF_DATA) + return err("ELF file has different endianness."); + if (ehdr->e_ident[EI_CLASS] != ELF_CLASS) + return err("ELF file has different word size."); + + /* Check the target architecture. + */ + if (ehdr->e_machine != ELF_ARCH) + return err("ELF file created for different architecture."); + + /* Verify the sizes of the ELF header and the program segment + * header table entries. + */ + if (ehdr->e_ehsize != sizeof(Elf_Ehdr)) + return err("unrecognized ELF header size."); + if (ehdr->e_phentsize != sizeof(Elf_Phdr)) + return err("unrecognized program segment header size."); + + /* Finally, check the file type. + */ + if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) + return err("not an executable or shared-object library."); + + return TRUE; +} + +/* readphdrtable() loads the program segment header table into memory. + */ +static int readphdrtable(int fd, Elf_Ehdr const *ehdr, Elf_Phdr **phdrs) +{ + size_t size; + + if (!ehdr->e_phoff || !ehdr->e_phnum) + return err("ELF file has no program header table."); + + size = ehdr->e_phnum * sizeof **phdrs; + if (!(*phdrs = malloc(size))) + return err("Out of memory!"); + + errno = 0; + if (read(fd, *phdrs, size) != (ssize_t)size) + return ferr("missing or incomplete program segment header table."); + + return TRUE; +} + +/* getmemorysize() determines the offset of the last byte of the file + * that is referenced by an entry in the program segment header table. + * (Anything in the file after that point is not used when the program + * is executing, and thus can be safely discarded.) + */ +static int getmemorysize(Elf_Ehdr const *ehdr, Elf_Phdr const *phdrs, + unsigned long *newsize) +{ + Elf_Phdr const *phdr; + unsigned long size, n; + int i; + + /* Start by setting the size to include the ELF header and the + * complete program segment header table. + */ + size = ehdr->e_phoff + ehdr->e_phnum * sizeof *phdrs; + if (size < sizeof *ehdr) + size = sizeof *ehdr; + + /* Then keep extending the size to include whatever data the + * program segment header table references. + */ + for (i = 0, phdr = phdrs ; i < ehdr->e_phnum ; ++i, ++phdr) { + if (phdr->p_type != PT_NULL) { + n = phdr->p_offset + phdr->p_filesz; + if (n > size) + size = n; + } + } + + *newsize = size; + return TRUE; +} + +/* truncatezeros() examines the bytes at the end of the file's + * size-to-be, and reduces the size to exclude any trailing zero + * bytes. + */ +static int truncatezeros(int fd, unsigned long *newsize) +{ + unsigned char contents[1024]; + unsigned long size, n; + + size = *newsize; + do { + n = sizeof contents; + if (n > size) + n = size; + if (lseek(fd, size - n, SEEK_SET) == (off_t)-1) + return ferr("cannot seek in file."); + if (read(fd, contents, n) != (ssize_t)n) + return ferr("cannot read file contents"); + while (n && !contents[--n]) + --size; + } while (size && !n); + + /* Sanity check. + */ + if (!size) + return err("ELF file is completely blank!"); + + *newsize = size; + return TRUE; +} + +/* modifyheaders() removes references to the section header table if + * it was stripped, and reduces program header table entries that + * included truncated bytes at the end of the file. + */ +static int modifyheaders(Elf_Ehdr *ehdr, Elf_Phdr *phdrs, + unsigned long newsize) +{ + Elf_Phdr *phdr; + int i; + + /* If the section header table is gone, then remove all references + * to it in the ELF header. + */ + if (ehdr->e_shoff >= newsize) { + ehdr->e_shoff = 0; + ehdr->e_shnum = 0; + ehdr->e_shentsize = 0; + ehdr->e_shstrndx = 0; + } + + /* The program adjusts the file size of any segment that was + * truncated. The case of a segment being completely stripped out + * is handled separately. + */ + for (i = 0, phdr = phdrs ; i < ehdr->e_phnum ; ++i, ++phdr) { + if (phdr->p_offset >= newsize) { + phdr->p_offset = newsize; + phdr->p_filesz = 0; + } else if (phdr->p_offset + phdr->p_filesz > newsize) { + phdr->p_filesz = newsize - phdr->p_offset; + } + } + + return TRUE; +} + +/* commitchanges() writes the new headers back to the original file + * and sets the file to its new size. + */ +static int commitchanges(int fd, Elf_Ehdr const *ehdr, Elf_Phdr *phdrs, + unsigned long newsize) +{ + size_t n; + + /* Save the changes to the ELF header, if any. + */ + if (lseek(fd, 0, SEEK_SET)) + return ferr("could not rewind file"); + errno = 0; + if (write(fd, ehdr, sizeof *ehdr) != sizeof *ehdr) + return err("could not modify file"); + + /* Save the changes to the program segment header table, if any. + */ + if (lseek(fd, ehdr->e_phoff, SEEK_SET) == (off_t)-1) { + err("could not seek in file."); + goto warning; + } + n = ehdr->e_phnum * sizeof *phdrs; + if (write(fd, phdrs, n) != (ssize_t)n) { + err("could not write to file"); + goto warning; + } + + /* Eleventh-hour sanity check: don't truncate before the end of + * the program segment header table. + */ + if (newsize < ehdr->e_phoff + n) + newsize = ehdr->e_phoff + n; + + /* Chop off the end of the file. + */ + if (ftruncate(fd, newsize)) { + err("could not resize file"); + goto warning; + } + + return TRUE; + + warning: + return err("ELF file may have been corrupted!"); +} + +/* main() loops over the cmdline arguments, leaving all the real work + * to the other functions. + */ +int main(int argc, char *argv[]) +{ + int fd; + Elf_Ehdr ehdr; + Elf_Phdr *phdrs; + unsigned long newsize; + char **arg; + int failures = 0; + + if (argc < 2 || argv[1][0] == '-') { + printf("Usage: sstrip FILE...\n" + "sstrip discards all nonessential bytes from an executable.\n\n" + "Version 2.0 Copyright (C) 2000,2001 Brian Raiter.\n" + "This program is free software, licensed under the GNU\n" + "General Public License. There is absolutely no warranty.\n"); + return EXIT_SUCCESS; + } + + progname = argv[0]; + + for (arg = argv + 1 ; *arg != NULL ; ++arg) { + filename = *arg; + + fd = open(*arg, O_RDWR); + if (fd < 0) { + ferr("can't open"); + ++failures; + continue; + } + + if (!(readelfheader(fd, &ehdr) && + readphdrtable(fd, &ehdr, &phdrs) && + getmemorysize(&ehdr, phdrs, &newsize) && + truncatezeros(fd, &newsize) && + modifyheaders(&ehdr, phdrs, newsize) && + commitchanges(fd, &ehdr, phdrs, newsize))) + ++failures; + + close(fd); + } + + return failures ? EXIT_FAILURE : EXIT_SUCCESS; +} + +#else + +int main() +{ + return (EXIT_SUCCESS); +} + +#endif diff --git a/synth.c b/synth.c new file mode 100644 index 0000000..679ca94 --- /dev/null +++ b/synth.c @@ -0,0 +1,183 @@ +#include "synth.h" +#include "play.h" +#include "dl_init.h" +#include + +#define msin(x) __builtin_sinf(x) +#define mcos(x) __builtin_cosf(x) +#define mfmodf(x,y) fn.fmodf(x,y) + +extern float current_time; +extern Song song; + +float mtan(float x) +{ + float sin_x, cos_x; + #ifdef X86_ASM + __asm__("fsincos" : "=t" (cos_x), "=u" (sin_x) : "0" (x)); + #else + sin_x=msin(x); + cos_x=mcos(x); + #endif + + return sin_x/cos_x; +} + +//#define SYNTH_HACKS + +// Evaluates the envelope e at position pos +// Lineal interpolation +float getADSR(Envelope *e, float pos) +{ + float p=pos*100.0f; + float A=e->A; + if (p < 0) + return 9.96589660645e-05f; + if (p < A) + return (p/A)+9.96589660645e-05f; + + p -= A; + + float D=e->D; + float S=e->S*0.00994873046875f; + if (p <= D) + return (1.0f-(p * (1.0f - S)) / D); + + p -= D; + + float sustain_time=e->sustain_time; + if (p <= sustain_time) + return S; + + p -= sustain_time; + + float R=e->R; +#ifndef SYNTH_HACKS + if (p < R) + return S - S * (p/R); + return 0.0f; +#else + return S - S * (p/R); +#endif +} + +float detune(int coarse, int fine) +{ + return fn.powf(2.0f, (coarse+(fine/100.0f))/12.0f); +} + + +int synth(Voice *v, int len, float *mix_buf) +{ + Instrument *ins=&song.insts[v->ins]; + //float pitch_sine = v->pitch * ins->sine_detune; + float pitch_square= v->pitch * detune(ins->square_detune_coarse, ins->square_detune_fine); + float pitch_saw = v->pitch * detune(ins->saw_detune_coarse, ins->saw_detune_fine); + float pitch_env, vol, res, t; + int i; + + for (i=0; ipos+i)*invSAMPLE_RATE; + v->cur_vol = vol = getADSR(&song.envelopes[ins->vol_envelope], t); + if(ins->pitch_envelope) + pitch_env = getADSR(&song.envelopes[ins->pitch_envelope], t); + else + pitch_env = 1.0f; + + // Calc. and mix the oscillators + // Noise + res = 0.00994873046875f*ins->noise_vol*(2.0f*whitenoise()-1.0f) ; + + // Sine + //res += ins->sine_vol * msin(DOSPI*pitch_sine*pitch_env*t); + + + // Square + + float sqvol=ins->square_vol*0.00994873046875f; + if (mfmodf(t, 1.0f/(pitch_square*pitch_env)) > (0.5f/(pitch_square*pitch_env))) + res += sqvol; + else + res -= sqvol; + + + // Sine + //float sqvol=ins->square_vol*0.00994873046875f; + //res += sqvol * msin(DOSPI*pitch_square*pitch_env*t); + + + + // Saw + res += 0.00994873046875f*ins->saw_vol * 2.0f*__builtin_fabsf((mfmodf(t*pitch_saw*pitch_env, 2.0f) - 1.0f))-1.0f; + + + // Apply the ADSR + res *= vol; + + // Calculamos el valor del cutoff aplicando LFO + // TODO: Comprobar si vale la pena eliminar este if + float cutoff, lfo_freq; + if (ins->lfo_freq < 0) + { + lfo_freq=-ins->lfo_freq; + t=current_time; + } + else + { + lfo_freq=ins->lfo_freq; + } + lfo_freq *= 0.099609375f; + cutoff= ins->cutoff + ins->lfo_amp * mcos(DOSPI * lfo_freq * t); + + // TODO: Cambiar el factor de la resonancia para + // ajustar el rango a valores mas utiles. + // ahora mismo va de 0.0 a 2.55 con incrementos de 0.01 y + // no parece que > 1.5 sea util + t = ins->resonance*0.00994873046875f; + + // Filter coefficients + float c, c2,a1,a2,b1,b2; + + // This is common to high-pass and low-pass + float param_tan = PI_samplerate * cutoff; + + if (cutoff > 0.0f) // Low-pass + { + c=1.0f / mtan(param_tan); + c2 = c*c; + + a1 = 1.0f / ( 1.0f + t*c + c2); + a2 = 2.0f * a1; + b1 = 2.0f * ( 1.0f - c2) * a1; + } + + else // High-pass + { + c = mtan(-param_tan); + c2 = c*c; + + a1 = 1.0f / ( 1.0f + t*c + c2); + a2 = -2.0f * a1; + b1 = 2.0f * ( c2 - 1.0f) * a1; + } + + b2 = ( 1.0f - t*c + c2) * a1; + + v->yn[0] = a1*res + a2*v->xn[1] + a1*v->xn[2] - + b1*v->yn[1] - b2*v->yn[2]; + + v->xn[2]=v->xn[1]; + v->xn[1]=res; + v->yn[2]=v->yn[1]; + v->yn[1]=v->yn[0]; + + mix_buf[i] += v->yn[0] * v->vol; + } + + v->pos+=len; + + if (vol > 0.0f) + return 1; + return 0; +} diff --git a/synth.h b/synth.h new file mode 100644 index 0000000..a39a67d --- /dev/null +++ b/synth.h @@ -0,0 +1,74 @@ +#ifndef _SYNTH_H_ +#define _SYNTH_H_ + + +#define BUFFER_SIZE 1024 +#define SAMPLE_RATE 44032.0f +#define invSAMPLE_RATE 2.26497650146e-05f + +#define FLOAT2INTCAST(x) (*((int*)(&x))) +#define FLOAT2UINTCAST(x) (*((unsigned int*)(&x))) + +#define PI_X 0x40490FDB +#define DOSPI_X 0x40C90FDB +#define PI_2_X 0x3FC90FDB + +#define PI 3.140625f +#define PI_samplerate 7.10487365723e-05f +#define DOSPI 6.28125f +#define DOSPI_samplerate 0.000142097473145f + +typedef unsigned char U8; +typedef signed char S8; + +typedef struct _Envelope +{ + U8 A, D, S, R; // In 1/100ths of a second except S which is vol*100 + U8 sustain_time; // In 1/100ths of a second +} Envelope; + +typedef struct _Instrument +{ + // Filter + float cutoff; // >0 LP; <0 HP + float lfo_amp; + S8 lfo_freq; + U8 resonance; // in 1/100ths + + S8 square_detune_coarse; // in tones + S8 square_detune_fine; // in cents + S8 saw_detune_coarse; + S8 saw_detune_fine; + + U8 square_vol; + U8 saw_vol; + U8 noise_vol; + + U8 vol_envelope; + U8 pitch_envelope; + +} Instrument; + + +typedef struct _Voice +{ + float pitch; + float vol; + float cur_vol; + + float xn[3]; + float yn[3]; + + int pos; // position in samples since the start + U8 ins; + U8 active; // { 0 ==> inactiva, (not 0) ==> activa } + + +} Voice; + +extern int synth(Voice *c, int len, float *mix_buf); +#define whitenoise() (fn.rand()/(float)RAND_MAX) +#define rand_4k() (fn.rand()) +//extern float whitenoise(); +extern float detune(int coarse, int fine); +#endif