void *Datum_split_(Datum *self, void *delimsList) /* returns a List */ { List *delims = (List *)delimsList; List *results = List_new(); size_t i, last = 0; for (i = 0; i < self->size; i ++) { Datum d = Datum_datumAt_(self, i); size_t j; for (j = 0; j < (size_t)List_size(delims); j ++) { Datum *delim = (Datum *)List_at_(delims, j); if (Datum_beginsWith_(&d, delim)) { List_append_(results, Datum_newFrom_to_(self, last, i)); last = i + delim->size; i = last - 1; /* since for() will increment it */ break; } } } if (last != self->size) { List_append_(results, Datum_newFrom_to_(self, last, self->size)); } return results; }
void IoBlock_copy_(IoBlock *self, IoBlock *other) { DATA(self)->message = IOREF(DATA(other)->message); { List *l1 = DATA(self)->argNames; List_removeAll(l1); LIST_FOREACH(DATA(other)->argNames, i, v, List_append_(l1, IOREF(v)); ); }
void IoAudioMixer_addEvent_(IoAudioMixer *self, AudioEvent *event) { List *events = DATA(self)->events; List_append_(events, event); List_qsort(events, (void *)AudioEvent_compare); #ifdef DEBUG IoAudioMixer_showEvents(self); #endif }
void IoLexer_buildLineIndex(IoLexer *self) { char *s = self->s; List_removeAll(self->charLineIndex); List_append_(self->charLineIndex, s); while (*s) { if (*s == '\n') { List_append_(self->charLineIndex, s); } s ++; } List_append_(self->charLineIndex, s); self->lineHint = 0; }
void IoMessage_setCachedArg_toInt_(IoMessage *self, int n, int anInt) { // optimized to avoid creating a number unless necessary IoMessage *arg = NULL; while (!(arg = List_at_(DATA(self)->args, n))) { List_append_(DATA(self)->args, IOREF(IoMessage_new(IOSTATE))); } IoMessage_rawSetCachedResult_(arg, IONUMBER(anInt)); }
void IoState_setupCachedNumbers(IoState *self) { int i; self->cachedNumbers = List_new(); for (i = MIN_CACHED_NUMBER; i < MAX_CACHED_NUMBER + 1; i ++) { IoNumber *number = IoNumber_newWithDouble_(self, i); List_append_(self->cachedNumbers, number); IoState_retain_(self, number); } }
void IoMessage_copy_(IoMessage *self, IoMessage *other) { IoMessage_rawSetName_(self, DATA(other)->name); { List *l1 = DATA(self)->args; List *l2 = DATA(other)->args; size_t i, max = List_size(l2); List_removeAll(l1); for (i = 0; i < max; i ++) { List_append_(l1, IOREF(List_rawAt_(l2, i))); } } IoMessage_rawSetNext_(self, DATA(other)->next); IoMessage_rawSetCachedResult_(self, DATA(other)->cachedResult); IoMessage_rawCopySourceLocation(self, other); }
void Levels_attachToTopAndPush(Levels *self, IoMessage *msg, int precedence) { Level *level = NULL; { Level *top = List_top(self->stack); Level_attachAndReplace(top, msg); } { // TODO: Check for overflow of the pool. if (self->currentLevel >= IO_OP_MAX_LEVEL) { IoState_error_(IoObject_state(msg), NULL, "compile error: Overflowed operator stack. Only %d levels of operators currently supported.", IO_OP_MAX_LEVEL-1); } level = &self->pool[self->currentLevel++]; Level_setAwaitingFirstArg(level, msg, precedence); List_append_(self->stack, level); } }
IO_METHOD(IoMessage, setArguments) { /*doc Message setArguments(aListOfMessages) Sets the arguments of the receiver to deep copies of those contained in aListOfMessages. Returns self. */ IoList *ioList = IoMessage_locals_listArgAt_(m, locals, 0); List *newArgs = IoList_rawList(ioList); List_removeAll(DATA(self)->args); LIST_FOREACH(newArgs, i, argMessage, if (!ISMESSAGE((IoMessage *)argMessage)) { IoState_error_(IOSTATE, m, "arguments_() takes a list containing only Message objects"); } List_append_(DATA(self)->args, IOREF((IoMessage *)argMessage)); );
void Levels_reset(Levels *self) { int i; self->currentLevel = 1; for (i = 0; i < IO_OP_MAX_LEVEL; i ++) { Level *level = &self->pool[i]; level->type = UNUSED; } { Level *level = &self->pool[0]; level->message = NULL; level->type = NEW; level->precedence = IO_OP_MAX_LEVEL; } List_removeAll(self->stack); List_append_(self->stack, &self->pool[0]); }
IoMessage *IoMessage_deepCopyOf_(IoMessage *self) { IoMessage *child = IoMessage_new(IOSTATE); int i; /*printf("deep copying: %s\n", UArray_asCString(IoMessage_description(self)));*/ for (i = 0; i < IoMessage_argCount(self); i ++) { List_append_(DATA(child)->args, IOREF(IoMessage_deepCopyOf_(LIST_AT_(DATA(self)->args, i)))); } IoMessage_rawSetName_(child, DATA(self)->name); IoMessage_rawSetCachedResult_(child, (IoObject *)DATA(self)->cachedResult); if (DATA(self)->next) { IoMessage_rawSetNext_(child, IoMessage_deepCopyOf_(DATA(self)->next)); } /*printf("deep copy result: %s\n", UArray_asCString(IoMessage_description(child)));*/ return child; }
IoObject *IoEventManager_addEvent(IoEventManager *self, IoObject *locals, IoMessage *m) { IoEvent *event = IoMessage_locals_eventArgAt_(m, locals, 0); struct event *ev = IoEvent_rawEvent(event); int fd = IoMessage_locals_intArgAt_(m, locals, 1); int eventType = IoMessage_locals_intArgAt_(m, locals, 2); double timeout = IoMessage_locals_doubleArgAt_(m, locals, 3); struct timeval tv = timevalFromDouble(timeout); //printf("IoEventManager_addEvent type:%i descriptor:%i\n", eventType, fd); //printf("fcntl(fd, F_GETFL, NULL) = %i\n", fcntl(fd, F_GETFL, NULL)); if (eventType != 0 && !RawDescriptor_isValid(fd)) { return IoError_newWithMessageFormat_(IOSTATE, "IoEventManager_addEvent: attempt to add bad file descriptor %i", fd); } List_append_(DATA(self)->activeEvents, IOREF(event)); event_set(ev, fd, eventType, IoEvent_handleEvent, event); event_base_set(DATA(self)->eventBase, ev); if (timeout < 0) { event_add(ev, NULL); // no timeout } else { event_add(ev, &tv); } return self; }
void IoList_rawAddBaseList_(IoList *self, List *otherList) { List *list = DATA(self); LIST_FOREACH(otherList, i, v, List_append_(list, IOREF((IoObject *)v)); );
void IoList_rawAppend_(IoList *self, IoObject *v) { List_append_(DATA(self), IOREF(v)); IoObject_isDirty_(self, 1); }
int IoAudioMixer_mixOneChunk(IoAudioMixer *self, IoObject *locals, IoMessage *m) { UArray *mixBuffer = DATA(self)->mixBuffer; List *sounds = DATA(self)->sounds; List *soundsToRemove = DATA(self)->soundsToRemove; AudioEvent *e = List_top(DATA(self)->events); List *activeEvents = DATA(self)->activeEvents; int frame; /*int samplesPerBuffer = DATA(self)->samplesPerBuffer;*/ int samplesPerBuffer = UArray_size(DATA(self)->mixBuffer) / (sizeof(float) * 2); UArray_setAllBytesTo_(mixBuffer, 0); while ( e && (!e->ioTriggerSound)) { List_append_(DATA(self)->activeEvents, List_pop(DATA(self)->events)); e = List_top(DATA(self)->events); } if (List_size(activeEvents)) IoAudioMixer_processActiveEvents(self); if (List_size(soundsToRemove)) IoAudioMixer_processSoundRemovals(self); for (frame = 0; frame < samplesPerBuffer; frame ++) { int index = frame * 2; int i; float *ol = UArray_floatPointerAt_(mixBuffer, index); float *or = UArray_floatPointerAt_(mixBuffer, index+1); for (i = 0; i < List_size(sounds); i++) { IoSound *ioSound = List_at_(sounds, i); Sound *sound = IoSound_rawSound(ioSound); float left, right; char done = Sound_nextFloat(sound, &left, &right); if (done && !Sound_isLooping(sound)) { List_append_(soundsToRemove, ioSound); continue; } (*ol) += left; (*or) += right; while (e && ((!e->ioTriggerSound) || ((e->ioTriggerSound == ioSound) && (e->sample == Sound_position(sound)))) ) { List_append_(DATA(self)->activeEvents, List_pop(DATA(self)->events)); e = List_top(DATA(self)->events); } } (*ol) *= DATA(self)->scale; (*or) *= DATA(self)->scale; if (List_size(activeEvents)) IoAudioMixer_processActiveEvents(self); if (List_size(soundsToRemove)) IoAudioMixer_processSoundRemovals(self); } /* adjust pitch and tempo */ { //double t1 = ((double)clock())/((double)CLOCKS_PER_SEC); //double t2; int receivedSamples = 1; SoundTouch_putSamples(DATA(self)->soundTouch, (float *)UArray_bytes(mixBuffer), samplesPerBuffer); //printf("put %i\n", samplesPerBuffer); //while (receivedSamples) { UArray_setSize_(DATA(self)->buffer, 10000*8); receivedSamples = SoundTouch_receiveSamples(DATA(self)->soundTouch, (float *)UArray_bytes(DATA(self)->buffer), UArray_size(DATA(self)->buffer) / (sizeof(float) * 2)); UArray_setSize_(DATA(self)->buffer, receivedSamples * (sizeof(float) * 2)); //printf("received %i\n", receivedSamples); if (receivedSamples) { if (receivedSamples < 5000) { #ifdef DEBUG printf("non-blocking write\n"); #endif IoMessage_locals_performOn_(DATA(self)->nonBlockingWriteMessage, self, DATA(self)->ioAudioDevice); } else { IoMessage_locals_performOn_(DATA(self)->writeMessage, self, DATA(self)->ioAudioDevice); } } #ifdef DEBUG t2 = ((double)clock())/((double)CLOCKS_PER_SEC); printf("tempo: %1.1f %i -> %i in %0.2f sec\n", DATA(self)->tempo, samplesPerBuffer, receivedSamples, (float)(t2 - t1)); #endif } //printf("\n"); return receivedSamples; } /* need to change this to be dynamic, so we can easily record the output */ /*IoAudioDevice_justWrite(DATA(self)->ioAudioDevice, locals, m, buffer);*/ return UArray_size(DATA(self)->buffer) / 8; }
void IoAudioMixer_justAddSound_(IoAudioMixer *self, IoSound *ioSound) { /*printf("add sound %p\n", (void *)ioSound);*/ List_append_(DATA(self)->sounds, ioSound); Sound_setIsPlaying_(IoSound_rawSound(ioSound), 1); }