buffer_t* get_free_buffer(){ node_t* temp_node; node_t node; static int buffer_address_count = 0; /*look for a pre-existing free buffer*/ for (temp_node = buffer_list;temp_node;temp_node=temp_node->next){ if (BUFF_FREE == buffer_get_flags((buffer_t*)temp_node->data)) return (buffer_t*)temp_node->data; } temp_node = &node; /*no free buffer found so create one*/ if (!(temp_node->data = (void*)buffer_alloca(buffer_address_count++, soundtank_engine->period_size))) return 0; if (!(temp_node = ll_append(&buffer_list, temp_node->data))){ buffer_dealloca((buffer_t*)temp_node->data); return 0; } if (buffer_address_count == 32000) buffer_address_count = 0; /*as bill the cat says: ack ack ack*/ buffer_zero((buffer_t*)temp_node->data); return (buffer_t*)temp_node->data; }
// Returns a malloced Buffer of a given size. Buffer buffer_alloc(size_t size) { Buffer buffer; buffer.capacity = size; buffer.offset = 0; buffer.data = malloc(size); buffer.size = malloc_size(buffer.data); buffer_zero(&buffer); if (getenv("DEBUG_BUFFER")) print_trace("%p: buffer_alloc\n", buffer.data); return buffer; }
// Frees a buffer, destroying all data. void buffer_free(Buffer *buffer) { if (getenv("DEBUG_BUFFER")) print_trace("%p: buffer_free\n", buffer->data); if(malloc_size(buffer->data)) { buffer_zero(buffer); free(buffer->data); buffer->data = NULL; buffer->capacity = 0; buffer->size = 0; } else { error("DOUBLE FREE!"); } }
int main() { struct buffer *a, *b; a = buffer_new(); b = buffer_new(); buffer_putc(a, 'a'); buffer_putc(a, 'g'); buffer_copy(b, a, buffer_size(a)); buffer_copy(b, a, buffer_size(a)); buffer_zero(b); printf("buf sz = %d\n", buffer_size(b)); return 0; }
// Clears a buffer and sets the offset to 0. void buffer_reset(Buffer *buffer) { buffer_zero(buffer); buffer->offset = 0; }
int main (int ac, char **av) { sisy_t sisy; bank_t bank; audio_t audio; int done=0; init_tab(); memset(&sisy, 0, sizeof(sisy)); bank.pos = 0; bank.watches_size = 0; bank.name = "sisy IO"; bank.size = sizeof(sisy_IO_t); bank.data = &sisy.IO; bank.symtab = IO_symtab; bank_push(&bank); sisy_getopt(ac, av); instru_path[instru_path_size] = Malloc(strlen(getenv("HOME")) + strlen("/.sisy/") + 200); strcat(instru_path[instru_path_size], getenv("HOME")); strcat(instru_path[instru_path_size++], "/.sisy/"); instru_path[instru_path_size++] = "/usr/share/sisy/"; sisy.buffer = buffer_create(); printf("Init midi: "); if(sisy_midi_init(&sisy, midi_device) < 0) { fprintf(stderr, "ERROR: got some troubles while opening midi device %s\n", midi_device); goto error; } printf("Ok\nInit audio: "); if(audio_init(&audio, audio_device) < 0) { fprintf(stderr, "ERROR: got some troubles while opening audio device %s\n", audio_device); goto error; } printf("Ok\nEnter in main loop...\n"); while(!done) { int t; done=1; ck_err(buffer_zero(sisy.buffer)<0); // printf("%d\r", midi_timestamp_get()); for(t=0; t<sisy.nb_tracks; t++) { sisy_track_t *track=&sisy.tracks[t]; if(!track->EOT) { done=0;//We are not done ! ck_err(bank_push(&track->midi.bank)); ck_err(buffer_zero(track->buffer) < 0); ck_err(sisy_track_process(track) < 0); ck_err(bank_pop_check(&track->midi.bank)); ck_err(buffer_mix(track->buffer, sisy.buffer)); } } /* if(!is_buffer_flat(sisy.buffer)) */ /* printf("sisy: buffer qui bouge\n"); */ ck_err(audio_write(&audio, sisy.buffer)<0); } /* ck_err(bank_pop_check(&sisy.midi.bank)); */ /* ck_err(bank_pop_check(&bank)); */ audio_quit(&audio); return 0; error: return -1; }
static int /* TOC: * process midi messages * process audio messages */ sisy_track_process(sisy_track_t *track) { midi_msg_t mmsg; unsigned char chan; unsigned char buff[BUFF_SIZE]; int c; midi_timestamp(track->midi.midi, midi_timestamp_get()); // printf("midi_timestamp_get(): %d\n", midi_timestamp_get()); dbg(DBG_MIDI, "sisy_track_process"); while(midi_get_msg (track->midi.midi, &mmsg) >= 0 && !MIDI_MSG_NULL (&mmsg)) { if(dbg_filter&DBG_MIDI) printf("sisy_midi_track_process: %x: ", MIDI_MSG_STATUS(&mmsg)); if (MIDI_MSG_DATA (&mmsg)) { ck_err (midi_get_data (track->midi.midi, buff, BUFF_SIZE)<0); continue;//What? } switch(MIDI_MSG_TYPE(&mmsg))//System level { case MIDI_SYSTEM: if(dbg_filter&DBG_MIDI) printf("system: "); switch(MIDI_MSG_STATUS(&mmsg)) { case MIDI_SYS_META: if(dbg_filter&DBG_MIDI) printf("meta: %x: ", MIDI_MSG_DATA1(&mmsg)); switch(MIDI_MSG_DATA1(&mmsg)) { case MIDI_SYS_META_TEMPO: if(dbg_filter&DBG_MIDI) printf("tempo: %x\n", MIDI_MSG_TEMPO(&mmsg)); midi_tempo_set(MIDI_MSG_TEMPO(&mmsg)); break; case MIDI_SYS_META_ENDOFTRACK: track->EOT=1; if(dbg_filter&DBG_MIDI) puts("EOT"); break; default: if(dbg_filter&DBG_MIDI) puts("default"); } break; default: if(dbg_filter&DBG_MIDI) puts("default"); } break; case MIDI_PROG_CHNG: case MIDI_NOTE_ON: case MIDI_NOTE_OFF: if(dbg_filter&DBG_MIDI) printf("note on|off msg: %x\n", MIDI_MSG_TYPE(&mmsg)); chan=MIDI_MSG_CHAN(&mmsg); if(!track->chan[chan]) ck_err(!(track->chan[chan] = instru_create("PIANO"))); ck_err(instru_midi_msg(track->chan[chan], &mmsg)<0); break; default: if(dbg_filter&DBG_MIDI) printf("default msg: %x\n", MIDI_MSG_TYPE(&mmsg)); } } for(c=0; c<SISY_NB_CHAN; c++) { instru_t *chan=track->chan[c]; if(chan) { ck_err(buffer_zero(chan->buffer)); instru_process(chan, BUFFER_SIZE); ck_err(buffer_mix(chan->buffer, track->buffer)); } } /* if(!is_buffer_flat(track->buffer)) */ /* printf("sisy_track_process: buffer qui bouge\n"); */ return 0; error: return -1; }