static void updatePort(struct nodeInstanceData *context, VuoInteger newUdpPort) { context->udpPort = newUdpPort; VuoRelease(context->oscManager); context->oscManager = VuoOscIn_make(newUdpPort); VuoRetain(context->oscManager); }
static void updateServer(struct nodeInstanceData *context, VuoText newServerName) { VuoRelease(context->serverName); context->serverName = newServerName; VuoRetain(context->serverName); VuoSyphonServer_setName(context->syphonServer, newServerName); }
static void updateDevice(struct nodeInstanceData *context, VuoAudioOutputDevice newDevice) { VuoAudioOutputDevice_release(context->device); context->device = newDevice; VuoAudioOutputDevice_retain(context->device); VuoRelease(context->audioManager); context->audioManager = VuoAudioOut_getShared(newDevice); VuoRetain(context->audioManager); }
static void updateDevice(struct nodeInstanceData *context, VuoMidiDevice newDevice) { VuoMidiDevice_release(context->device); context->device = newDevice; VuoMidiDevice_retain(context->device); VuoRelease(context->midiManager); context->midiManager = VuoMidiIn_make(newDevice); VuoRetain(context->midiManager); }
/** * @ingroup VuoMathExpression * Encodes the value as a JSON object. * * Includes the expression's variables in the JSON object, to be used when generating the Calculate node class. * However, the variables are ignored by VuoMathExpression_makeFromJson(). * * @eg{ * { * "expression" : "y = x + 4", * "inputVariables" : [ "x" ], * "outputVariables" : [ "y" ] * } * } */ json_object * VuoMathExpression_getJson(const VuoMathExpression me) { json_object *js = json_object_new_object(); json_object_object_add(js, "expression", VuoText_getJson(me.expression)); if (me.parser) { VuoList_VuoText inputVariables = VuoMathExpressionParser_getInputVariables(me.parser); json_object_object_add(js, "inputVariables", VuoList_VuoText_getJson(inputVariables)); VuoRelease(inputVariables); VuoList_VuoText outputVariables = VuoMathExpressionParser_getOutputVariables(me.parser); json_object_object_add(js, "outputVariables", VuoList_VuoText_getJson(outputVariables)); VuoRelease(outputVariables); } return js; }
static void playNextAudioFrame(struct nodeInstanceData *context, VuoOutputTrigger(decodedAudio, VuoList_VuoAudioSamples)) { if(context->lastAudioSamples) { // Send Audio if(VuoListGetCount_VuoAudioSamples(context->lastAudioSamples) > 0) { VuoAudioSamples as = VuoListGetValueAtIndex_VuoAudioSamples(context->lastAudioSamples, 1); decodedAudio(context->lastAudioSamples); } VuoRelease(context->lastAudioSamples); context->lastAudioSamples = NULL; } uint64_t cur_time = dispatch_time(DISPATCH_TIME_NOW, 0); if(!context->movie) return; context->lastAudioSamples = VuoListCreate_VuoAudioSamples(); double frameTimestampInSecs = 0; bool gotFrame = VuoMovie_getNextAudioSample(context->movie, context->lastAudioSamples, &frameTimestampInSecs); if(gotFrame) { VuoRetain(context->lastAudioSamples); context->lastAudioTimestamp = frameTimestampInSecs; } else { VLog("bad"); if(context->lastAudioSamples) VuoRelease(context->lastAudioSamples); context->lastAudioSamples = NULL; } uint64_t presentationTime = (cur_time + NSEC_PER_SEC * AUDIO_SEC_PER_SAMPLE - 100000); dispatch_source_set_timer(context->audio_timer, presentationTime, DISPATCH_TIME_FOREVER, NSEC_PER_SEC / 100000 ); }
static void setMovie(struct nodeInstanceData *context, const char *movieURL) { VuoMovie newMovie = VuoMovie_make(movieURL); // If VuoMovie_make fails to initialize properly, it cleans up after itself. // No need to call VuoMovie_free() if(newMovie == NULL) return; VuoRetain(newMovie); VuoRelease(context->movie); context->movie = newMovie; context->duration = VuoMovie_getDuration(context->movie); }
/** * @ingroup VuoText * Creates a new UTF-8 C string from @c value, or, if it's more than 30 Unicode characters long, creates an aposiopesis. * * @eg{Hello World!} * @eg{I would like to convey my gree...} */ char * VuoText_summaryFromValue(const VuoText value) { if (!value) return strdup(""); const int maxLength = 30; if (VuoText_length(value) <= maxLength) return strdup(value); VuoText abbreviation = VuoText_substring(value, 1, maxLength); VuoText ellipsis = VuoText_make("..."); VuoText summaryParts[2] = { abbreviation, ellipsis }; VuoText summaryWhole = VuoText_append(summaryParts, 2); char *summary = strdup(summaryWhole); VuoRetain(abbreviation); VuoRelease(abbreviation); VuoRetain(ellipsis); VuoRelease(ellipsis); VuoRetain(summaryWhole); VuoRelease(summaryWhole); return summary; }
static void pauseAudio(struct nodeInstanceData *context) { if( VuoMovie_containsAudio(context->movie) ) { if(context->audio_timer) { dispatch_source_cancel(context->audio_timer); dispatch_semaphore_wait(context->audio_timerCanceled, DISPATCH_TIME_FOREVER); dispatch_release(context->audio_timer); } context->audio_timer = NULL; if(context->lastAudioSamples) { VuoRelease(context->lastAudioSamples); context->lastAudioSamples = NULL; } } }
/** * Receives the data at the specified @c url. * * @return true upon success, false upon failure. * @todo Better error handling per https://b33p.net/kosada/node/4724 */ bool VuoUrl_fetch(const char *url, void **data, unsigned int *dataLength) { struct VuoUrl_curlBuffer buffer = {NULL, 0}; CURL *curl; CURLcode res; curl = curl_easy_init(); if (!curl) { VLog("Error: cURL initialization failed."); return false; } curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); // Don't use signals for the timeout logic, since they're not thread-safe. VuoText resolvedUrl = VuoUrl_normalize(url, true); VuoRetain(resolvedUrl); curl_easy_setopt(curl, CURLOPT_URL, resolvedUrl); VuoRelease(resolvedUrl); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, VuoUrl_curlCallback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&buffer); res = curl_easy_perform(curl); if(res != CURLE_OK) { if (res == CURLE_FILE_COULDNT_READ_FILE) VLog("Error: Could not read path: \"%s\"", resolvedUrl); else VLog("Error: cURL request failed: %s (%d)\n", curl_easy_strerror(res), res); return false; } curl_easy_cleanup(curl); *data = buffer.memory; *dataLength = buffer.size; return true; }
struct nodeInstanceData * nodeInstanceInit(void) { struct nodeInstanceData * instance = (struct nodeInstanceData *)malloc(sizeof(struct nodeInstanceData)); VuoRegister(instance, free); instance->glContext = VuoGlContext_use(); instance->imageRenderer = VuoImageRenderer_make(instance->glContext); VuoRetain(instance->imageRenderer); VuoList_VuoColor colors = VuoListCreate_VuoColor(); VuoRetain(colors); instance->shader = VuoShader_makeRadialGradientShader(colors, VuoPoint2d_make(0., 0.), 1., 1., 1.); VuoRetain(instance->shader); VuoRelease(colors); return instance; }
/** * @ingroup VuoText * Returns the index (starting at 1) of the last instance of @a substring in @a string. * Returns 0 if @a substring is not found. * * This function will find occurrences that consist of the same Unicode characters as @a substring, but won't find * occurrences that consist of the same Unicode string decomposed into a different number of Unicode characters. */ size_t VuoText_findLastOccurrence(const VuoText string, const VuoText substring) { if (! string) return 0; size_t foundIndex = 0; size_t stringLength = VuoText_length(string); size_t substringLength = VuoText_length(substring); for (size_t i = 1; i <= stringLength - substringLength + 1; ++i) { VuoText currSubstring = VuoText_substring(string, i, substringLength); if (VuoText_areEqual(substring, currSubstring)) foundIndex = i; VuoRetain(currSubstring); VuoRelease(currSubstring); } return foundIndex; }
static void pauseMovie(struct nodeInstanceData *context) { if (! context->movie) return; if(context->movie_timer) { dispatch_source_cancel(context->movie_timer); dispatch_semaphore_wait(context->movie_timerCanceled, DISPATCH_TIME_FOREVER); dispatch_release(context->movie_timer); } context->movie_timer = NULL; if(context->lastImage) { VuoRelease(context->lastImage); context->lastImage = NULL; } pauseAudio(context); }
/** * Finds and returns all the lights in the scene. * * If there are multiple ambient lights, returns the weighted (by alpha) average color and summed brightness. * * If there are no lights in the scene, returns some default lights. */ void VuoSceneObject_findLights(VuoSceneObject so, VuoColor *ambientColor, float *ambientBrightness, VuoList_VuoSceneObject *pointLights, VuoList_VuoSceneObject *spotLights) { VuoList_VuoColor ambientColors = VuoListCreate_VuoColor(); VuoRetain(ambientColors); *ambientBrightness = 0; *pointLights = VuoListCreate_VuoSceneObject(); *spotLights = VuoListCreate_VuoSceneObject(); float localModelviewMatrix[16]; VuoTransform_getMatrix(VuoTransform_makeIdentity(), localModelviewMatrix); VuoSceneObject_findLightsRecursive(so, localModelviewMatrix, ambientColors, ambientBrightness, *pointLights, *spotLights); if (!VuoListGetCount_VuoColor(ambientColors) && !VuoListGetCount_VuoSceneObject(*pointLights) && !VuoListGetCount_VuoSceneObject(*spotLights)) { *ambientColor = VuoColor_makeWithRGBA(1,1,1,1); *ambientBrightness = 0.05; // https://en.wikipedia.org/wiki/Three-point_lighting VuoSceneObject keyLight = VuoSceneObject_makePointLight(VuoColor_makeWithRGBA(1,1,1,1), .70, VuoPoint3d_make(-1,1,1), 5, .5); VuoListAppendValue_VuoSceneObject(*pointLights, keyLight); VuoSceneObject fillLight = VuoSceneObject_makePointLight(VuoColor_makeWithRGBA(1,1,1,1), .2, VuoPoint3d_make(.5,0,1), 5, 0); VuoListAppendValue_VuoSceneObject(*pointLights, fillLight); VuoSceneObject backLight = VuoSceneObject_makePointLight(VuoColor_makeWithRGBA(1,1,1,1), .15, VuoPoint3d_make(1,.75,-.5), 5, 0); VuoListAppendValue_VuoSceneObject(*pointLights, backLight); } else *ambientColor = VuoColor_average(ambientColors); VuoRelease(ambientColors); }