static enum mad_flow IoMP3Decoder_inputCallback(void *data, struct mad_stream *stream) { IoMP3Decoder *self = data; struct mad_decoder *decoder = &(DATA(self)->decoder); IoMessage_locals_performOn_(DATA(self)->willProcessMessage, self, self); if (DATA(self)->isRunning) { UArray *ba = IoSeq_rawUArray(DATA(self)->inputBuffer); UArray_removeRange(ba, 0, DATA(self)->lastInputPos); { size_t size = UArray_size(ba); UArray_setSize_(ba, size + MAD_BUFFER_GUARD); memset(UArray_bytes(ba) + size, 0x0, MAD_BUFFER_GUARD); UArray_setSize_(ba, size); } if (UArray_size(ba) == 0) { return MAD_FLOW_CONTINUE; } DATA(self)->lastInputPos = UArray_size(ba); mad_stream_buffer(stream, UArray_bytes(ba), UArray_size(ba)); } return DATA(self)->isRunning ? MAD_FLOW_CONTINUE : MAD_FLOW_STOP; }
IoCoroutine *IoCoroutine_newWithTry(void *state, IoObject *target, IoObject *locals, IoMessage *message) { IoCoroutine *self = IoCoroutine_new(state); //IoCoroutine_try(self, target, locals, message); IoCoroutine *currentCoro = (IoCoroutine *)IoState_currentCoroutine((IoState *)IOSTATE); IoCoroutine_rawSetRunTarget_(self, target); IoCoroutine_rawSetRunLocals_(self, locals); IoCoroutine_rawSetRunMessage_(self, message); IoCoroutine_rawSetParentCoroutine_(self, currentCoro); IoCoroutine *self = (IoCoroutine *)context; IoObject *result; IoState_setCurrentCoroutine_(IOSTATE, self); //printf("%p-%p start\n", (void *)self, (void *)DATA(self)->cid); result = IoMessage_locals_performOn_(IOSTATE->mainMessage, self, self); IoCoroutine_rawSetResult_(self, result); IoCoroutine_rawReturnToParent(self); // return from newwithTry return self; }
void IoEvConnection_ConnectionCloseCallback(struct evhttp_connection *con, void *arg) { IoObject *self = arg; //printf("IoEvConnection_ConnectionCloseCallback\n"); //IoEvConnection_free(self); IoMessage_locals_performOn_(IOSTATE->didFinishMessage, self, self); }
void IoEvDNSRequest_callback(int result, char type, int count, int ttl, void *addresses, void *arg) { IoEvDNSRequest *self = arg; //type is either DNS_IPv4_A or DNS_PTR or DNS_IPv6_AAAA IoObject_setSlot_to_(self, IOSYMBOL("ttl"), IONUMBER(ttl)); if(result == DNS_ERR_NONE) { IoList *ioAddresses = IoList_new(IOSTATE); IoObject_setSlot_to_(self, IOSYMBOL("addresses"), ioAddresses); int i; for (i = 0; i < count; i ++) { //addresses needs to be cast according to type uint32_t a = ((uint32_t *)addresses)[i]; struct in_addr addr; char *ip; addr.s_addr = htonl(get32(rr->rdata)); ip = (char *)inet_ntoa(addr); IoList_rawAppend_(ioAddresses, IOSYMBOL(ip)); } } else { IoObject_setSlot_to_(self, IOSYMBOL("error"), IOSYMBOL("fail")); } IoMessage *m = IoMessage_newWithName_label_(IOSTATE, IOSYMBOL("handleResponse"), IOSYMBOL("IoEvDNSRequest")); IoMessage_locals_performOn_(m, self, self); }
void IoMessage_opShuffle_(IoMessage *self) { if (IoObject_rawGetSlot_(self, IOSTATE->opShuffleSymbol) && IoMessage_name(self) != IOSTATE->noShufflingSymbol) { IoMessage_locals_performOn_(IOSTATE->opShuffleMessage, IOSTATE->lobby, self); } }
LmSSLResponse onSslError(LmSSL *ssl, LmSSLStatus status, void* data) { IoObject *self = data; IoMessage *m = IoMessage_newWithName_label_(IOSTATE, IOSYMBOL("handleSslError"), IOSYMBOL("Loudmouth")); IoObject *result = IoMessage_locals_performOn_(m, self, self); return ISFALSE(result) ? LM_SSL_RESPONSE_STOP : LM_SSL_RESPONSE_CONTINUE; }
IoObject *IoMessage_activate(IoMessage *self, IoObject *target, IoObject *locals, IoMessage *m, IoObject *slotContext) { //printf("activating self %s\n", CSTRING(IoMessage_name(self))); //printf("activating m %s\n", CSTRING(IoMessage_name(m))); return IoMessage_locals_performOn_(self, locals, locals); //return IoObject_perform(locals, locals, self); }
static enum mad_flow IoMP3Decoder_outputCallback(void *data, struct mad_header const *header, struct mad_pcm *pcm) { IoMP3Decoder *self = data; UArray *ba = IoSeq_rawUArray(DATA(self)->outputBuffer); unsigned int oldSize = UArray_size(ba); unsigned int newSize = oldSize + (pcm->length * 2 * sizeof(float)); UArray_setSize_(ba, newSize); if (!DATA(self)->isRunning) { return MAD_FLOW_STOP; } // MAD data is in 4 byte signed ints // and on separated (not interleaved channels) // so we interleave them here { float *out = (float *)(UArray_bytes(ba) + oldSize); unsigned int nsamples = pcm->length; mad_fixed_t const *left = pcm->samples[0]; mad_fixed_t const *right = pcm->samples[1]; if (pcm->channels == 2) { // this would be much faster as a vector op while (nsamples --) { *out = ((float)(*left)) / INT_MAX; out ++; *out = ((float)(*right)) / INT_MAX; out ++; left ++; right ++; } } else { while (nsamples --) { float f = ((float)(*left)) / INT_MAX; *out = f; out ++; *out = f; out ++; left ++; } } } IoMessage_locals_performOn_(DATA(self)->didProcessMessage, self, self); return DATA(self)->isRunning ? MAD_FLOW_CONTINUE : MAD_FLOW_STOP; }
IO_METHOD(IoFile, foreachLine) { /*doc File foreachLine(optionalLineNumber, line, message) For each line, set index to the line number of the line and line and execute aMessage. Example usage: <pre> aFile foreachLine(i, v, writeln("Line ", i, ": ", v)) aFile foreach(v, writeln("Line: ", v)) </pre> */ IoObject *result; IoSymbol *indexSlotName, *lineSlotName; IoMessage *doMessage; IoObject *newLine; int i = 0; IoState *state; IoFile_assertOpen(self, locals, m); IoMessage_foreachArgs(m, self, &indexSlotName, &lineSlotName, &doMessage); result = IONIL(self); state = IOSTATE; IoState_pushRetainPool(state); for (;;) { IoState_clearTopPool(state); newLine = IoFile_readLine(self, locals, m); if (ISNIL(newLine)) { break; } if (indexSlotName) { IoObject_setSlot_to_(locals, indexSlotName, IONUMBER(i)); } IoObject_setSlot_to_(locals, lineSlotName, newLine); result = IoMessage_locals_performOn_(doMessage, locals, locals); if (IoState_handleStatus(IOSTATE)) { break; } i ++; } IoState_popRetainPool(state); return result; }
IO_METHOD(IoNumber, repeat) { /*doc Number repeat(optionalIndex, expression) Evaluates message a number of times that corresponds to the receivers integer value. This is significantly faster than a for() or while() loop. */ IoMessage_assertArgCount_receiver_(m, 1, self); { IoState *state = IOSTATE; IoSymbol *indexSlotName; IoMessage *doMessage; double i, max = CNUMBER(self); IoObject *result = IONIL(self); if(IoMessage_argCount(m) > 1) { indexSlotName = IoMessage_name(IoMessage_rawArgAt_(m, 0)); doMessage = IoMessage_rawArgAt_(m, 1); } else { indexSlotName = 0; doMessage = IoMessage_rawArgAt_(m, 0); } IoState_pushRetainPool(state); for (i = 0; i < max; i ++) { /* if (result != locals && result != self) { IoState_immediatelyFreeIfUnreferenced_(state, result); } */ IoState_clearTopPool(state); if (indexSlotName) { IoObject_setSlot_to_(locals, indexSlotName, IONUMBER(i)); } result = IoMessage_locals_performOn_(doMessage, locals, locals); if (IoState_handleStatus(IOSTATE)) { break; } } IoState_popRetainPoolExceptFor_(IOSTATE, result); return result; } }
/*** Loudmouth callbacks ***/ void onXmppConnect(LmConnection *connection, int success, void* data) { IoObject *self = data; IoMessage *m; if(success == 1) { m = IoMessage_newWithName_label_(IOSTATE, IOSYMBOL("handleConnect"), IOSYMBOL("Loudmouth")); IoMessage_locals_performOn_(m, self, self); lm_connection_authenticate( connection, CSTRING(IoObject_getSlot_(self, IOSYMBOL("username"))), CSTRING(IoObject_getSlot_(self, IOSYMBOL("password"))), CSTRING(IoObject_getSlot_(self, IOSYMBOL("resource"))), onXmppAuth, data, NULL, NULL ); } else { m = IoMessage_newWithName_label_(IOSTATE, IOSYMBOL("handleConnectFailure"), IOSYMBOL("Loudmouth")); IoMessage_locals_performOn_(m, self, self); } }
void IoSandbox_printCallback(void *voidSelf, const UArray *ba) { IoSandbox *self = voidSelf; IoState *state = IOSTATE; IoSeq *buf = IoSeq_newWithUArray_copy_(IOSTATE, (UArray *)ba, 1); IoMessage *m = IoMessage_newWithName_(state, IOSYMBOL("printCallback")); IoMessage *arg = IoMessage_newWithName_returnsValue_(state, IOSYMBOL("buffer"), buf); IoMessage_addArg_(m, arg); IoMessage_locals_performOn_(m, state->lobby, self); }
void IoCoroutine_coroStart(void *context) // Called by Coro_Start() { IoCoroutine *self = (IoCoroutine *)context; IoObject *result; IoState_setCurrentCoroutine_(IOSTATE, self); //printf("%p-%p start\n", (void *)self, (void *)DATA(self)->cid); result = IoMessage_locals_performOn_(IOSTATE->mainMessage, self, self); IoCoroutine_rawSetResult_(self, result); IoCoroutine_rawReturnToParent(self); }
void onXmppAuth(LmConnection *connection, int success, void* data) { IoObject *self = data; IoMessage *m; if(success == 1) { m = IoMessage_newWithName_label_(IOSTATE, IOSYMBOL("handleAuthenticated"), IOSYMBOL("Loudmouth")); } else { m = IoMessage_newWithName_label_(IOSTATE, IOSYMBOL("handleAuthenticationFailure"), IOSYMBOL("Loudmouth")); } IoMessage_locals_performOn_(m, self, self); }
IO_METHOD(IoFile, foreach) { /*doc File foreach(optionalIndex, value, message) For each byte, set index to the index of the byte and value to the number containing the byte value and execute aMessage. Example usage: <p> <pre> aFile foreach(i, v, writeln("byte at ", i, " is ", v)) aFile foreach(v, writeln("byte ", v)) </pre> */ IoObject *result; IoSymbol *indexSlotName, *characterSlotName; IoMessage *doMessage; int i = 0; IoFile_assertOpen(self, locals, m); result = IONIL(self); IoMessage_foreachArgs(m, self, &indexSlotName, &characterSlotName, &doMessage); for (;;) { int c = getc(DATA(self)->stream); if (c == EOF) { break; } if (indexSlotName) { IoObject_setSlot_to_(locals, indexSlotName, IONUMBER(i)); } IoObject_setSlot_to_(locals, characterSlotName, IONUMBER(c)); result = IoMessage_locals_performOn_(doMessage, locals, locals); if (IoState_handleStatus(IOSTATE)) { break; } i ++; } return result; }
LmHandlerResult onXmppMessage (LmMessageHandler *handler, LmConnection *connection, LmMessage *m, void* data) { IoObject *self = data; IoList_rawAppend_( (IoList *)IoObject_getSlot_(self, IOSYMBOL("_msgsBuffer")), IOSYMBOL(lm_message_node_to_string(m->node)) ); IoMessage *io_m = IoMessage_newWithName_label_(IOSTATE, IOSYMBOL("parseMessage"), IOSYMBOL("Loudmouth")); IoMessage_locals_performOn_(io_m, self, self); return LM_HANDLER_RESULT_REMOVE_MESSAGE; }
IoObject *IoState_tryToPerform(IoState *self, IoObject *target, IoObject *locals, IoMessage *m) { IoCoroutine *tryCoro = IoCoroutine_newWithTry(self, target, locals, m); if (IoCoroutine_rawException(tryCoro) != self->ioNil) { IoState_exception_(self, tryCoro); } return IoCoroutine_rawResult(tryCoro); return IoMessage_locals_performOn_(m, locals, target); }
IO_METHOD(IoCoroutine, main) { IoObject *runTarget = IoCoroutine_rawRunTarget(self); IoObject *runLocals = IoCoroutine_rawRunLocals(self); IoObject *runMessage = IoCoroutine_rawRunMessage(self); if (runTarget && runLocals && runMessage) { return IoMessage_locals_performOn_(runMessage, runLocals, runTarget); } else { printf("IoCoroutine_main() missing needed parameters\n"); } return IONIL(self); }
IO_METHOD(IoDate, cpuSecondsToRun) { /*doc Date cpuSecondsToRun(expression) Evaluates message and returns a Number whose value is the cpu seconds taken to do the evaluation. */ IoMessage_assertArgCount_receiver_(m, 1, self); { double t2, t1 = clock(); IoMessage *doMessage = IoMessage_rawArgAt_(m, 0); IoMessage_locals_performOn_(doMessage, locals, locals); t2 = clock(); return IONUMBER((t2 - t1)/((double)CLOCKS_PER_SEC)); } }
IO_METHOD(IoMessage, doInContext) { /*doc Message doInContext(anObject, locals) Evaluates the receiver in the context of anObject. Optional <tt>locals</tt> object is used as message sender. <tt>anObject</tt> is used as sender otherwise. */ IoObject *context = IoMessage_locals_valueArgAt_(m, (IoObject *)locals, 0); if (IoMessage_argCount(m) >= 2) { locals = IoMessage_locals_valueArgAt_(m, (IoObject *)locals, 1); } else { // Default to using the context as the locals so that the common case of, // call argAt(2) doInContext(call sender) is easier. locals = context; } return IoMessage_locals_performOn_(self, locals, context); }
IoObject *IoDrawStuff_tryCallback(IoDrawStuff *self, IoMessage *m) { IoState *state = IoObject_state(proto); IoObject *tryCoro = DATA(self)->coroutine; IoObject *t = DATA(self)->eventTarget; IoObject *result = state->ioNil; //printf("IoDrawStuff_tryCallback(self, %p)\n", (void*)m); //printf("IoDrawStuff_tryCallback target: %p)\n", (void*)t); if(t) { IoMessage_locals_performOn_(m, t, t); if (IoCoroutine_rawException(tryCoro) != state->ioNil) IoState_exception_(state, tryCoro); IoCoroutine_clearStack(tryCoro); return IoCoroutine_rawResult(tryCoro); } return result; }
// Serialize/Deserialize char *IoMemcached_serialize(IoMemcached *self, IoObject *locals, IoObject *object, size_t *size, uint32_t *flags) { char *cvalue; if(ISSEQ(object)) { *flags = _FLAG_SEQUENCE; *size = IOSEQ_LENGTH(object); cvalue = (char *) malloc(*size); strncpy(cvalue, CSTRING(object), *size); } else if(ISNUMBER(object)) { *flags = _FLAG_NUMBER; double cnumber = IoNumber_asDouble(object); cvalue = (char *) malloc(128 * sizeof(char)); *size = snprintf(cvalue, 127, "%.16f", cnumber); } else if(ISNIL(object)) { *flags = _FLAG_NIL; *size = 3; cvalue = (char *) malloc(3 * sizeof(char)); strncpy(cvalue, "nil", 3); } else if(ISBOOL(object)) { *flags = _FLAG_BOOLEAN; *size = 1; cvalue = (char *) malloc(sizeof(char)); if(object == IOSTATE->ioTrue) strncpy(cvalue, "1", 1); if(object == IOSTATE->ioFalse) strncpy(cvalue, "0", 1); } else { *flags = _FLAG_OBJECT; IoMessage *serialize = IoMessage_newWithName_(IOSTATE, IOSYMBOL("serialized")); IoSeq *serialized = IoMessage_locals_performOn_(serialize, locals, object); *size = IOSEQ_LENGTH(serialized); cvalue = (char *) malloc(*size); strncpy(cvalue, CSTRING(serialized), *size); } return cvalue; }
void IoEvent_handleEvent(int fd, short eventType, void *context) { IoEvent *self = (IoEvent *)context; struct event *ev = IoEvent_rawEvent(self); IoEventManager *em = IoState_protoWithInitFunction_(IOSTATE, IoEventManager_proto); //printf("IoEvent_handleEvent type:%i descriptor:%i\n", eventType, fd); List_remove_(DATA(em)->activeEvents, self); //printf("e: %i\n", List_size(DATA(em)->activeEvents)); if (!ev) { printf("IoEventManager_addEvent: attempt to process an IoEvent with a 0x0 event struct - possible gc error"); exit(1); } event_del(ev); /* if (eventType != && !RawDescriptor_isValid(fd)) { printf("IoEvent_handleEvent: handleEvent type %i on bad file descriptor\n", eventType); } */ IoState_pushRetainPool(IOSTATE); { IoMessage *m = DATA(em)->handleEventMessage; IoMessage_setCachedArg_to_(m, 0, IOBOOL(self, eventType == EV_TIMEOUT)); IoMessage_locals_performOn_(m, self, self); } IoState_popRetainPool(IOSTATE); //printf("IoEvent_handleEvent %p done\n", (void *) context); }
void onXmppDisconnect(LmConnection *connection, LmDisconnectReason reason, void* data) { IoObject *self = data; IoMessage *m = IoMessage_newWithName_label_(IOSTATE, IOSYMBOL("handleDisconnect"), IOSYMBOL("Loudmouth")); IoMessage_locals_performOn_(m, self, self); }
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; }