static CDList * remix_plugin_init (RemixEnv * env, const char * path) { void * module; CDList * l; RemixPluginInitFunc init; module = dlopen (path, RTLD_NOW); if (!module) { remix_dprintf ("[remix_plugin_init] Unable to open %s: %s\n", path, dlerror ()); remix_set_error (env, REMIX_ERROR_SYSTEM); return CD_EMPTY_LIST; } /* Check that this module has not already been loaded (eg. if it is * a symlink etc.) */ for (l = modules_list; l; l = l->next) { if (l->data.s_pointer == module) { dlclose (module); return CD_EMPTY_LIST; } } modules_list = cd_list_append (env, modules_list, CD_POINTER(module)); if ((init = dlsym (module, "remix_load")) != NULL) { return init (env); } return CD_EMPTY_LIST; }
static CDList * init_dynamic_plugins_dir (RemixEnv * env, char * dirname) { CDList * plugins = cd_list_new (env); DIR * dir; struct dirent * dirent; char * name; static char buf[BUFLEN]; struct stat statbuf; dir = opendir (dirname); if (!dir) { /* fail silently */ return CD_EMPTY_LIST; } while ((dirent = readdir (dir)) != NULL) { name = dirent->d_name; remix_dprintf ("[init_dynamic_plugins_dir] trying %s ... ", name); snprintf (buf, BUFLEN, "%s/%s", dirname, name); if (stat (buf, &statbuf) == -1) { remix_set_error (env, REMIX_ERROR_SYSTEM); } else if (remix_stat_regular (statbuf.st_mode)) { plugins = cd_list_join (env, plugins, remix_plugin_init (env, buf)); } } closedir (dir); return plugins; }
static RemixCount remix_track_process (RemixEnv * env, RemixBase * base, RemixCount count, RemixStream * input, RemixStream * output) { RemixTrack * track = (RemixTrack *)base; CDList * l; RemixBase * layer; RemixStream * si, * so, * swap_stream; RemixCount remaining = count, processed = 0, n = 0; RemixCount mixlength = _remix_base_get_mixlength (env, track); remix_dprintf ("PROCESS TRACK (%p, +%ld, %p -> %p) @ %ld\n", track, count, input, output, remix_tell (env, base)); if (track->layers == RemixNone) { remix_set_error (env, REMIX_ERROR_NOOP); return 0; } while (remaining > 0) { l = track->layers; si = input; so = track->_mixstream_a; n = MIN (remaining, mixlength); while (l) { layer = (RemixBase *)l->data.s_pointer; if (si == input) { swap_stream = track->_mixstream_b; } else { swap_stream = si; remix_seek (env, (RemixBase *)si, 0, SEEK_SET); } if (l->next == RemixNone) { so = output; } else { remix_seek (env, (RemixBase *)so, 0, SEEK_SET); } n = remix_process (env, layer, n, si, so); l = l->next; /* swap si, st using swap_stream as evaluated above */ si = so; so = swap_stream; } remaining -= n; processed += n; } remix_dprintf ("[remix_track_process] processed %ld\n", processed); return processed; }
static RemixCount remix_gain_process (RemixEnv * env, RemixBase * base, RemixCount count, RemixStream * input, RemixStream * output) { RemixCount remaining = count, processed = 0, n; RemixCount output_offset; RemixCount mixlength = remix_base_get_mixlength (env, base); RemixBase * gain_envelope; RemixGain * gi = remix_base_get_instance_data (env, base); remix_dprintf ("PROCESS GAIN (%p, +%ld) @ %ld\n", base, count, remix_tell (env, base)); gain_envelope = (RemixBase *) (remix_get_parameter (env, base, GAIN_ENVELOPE_KEY)).s_pointer; if (gain_envelope == RemixNone) { remix_set_error (env, REMIX_ERROR_NOOP); return -1; } while (remaining > 0) { n = MIN (remaining, mixlength); output_offset = remix_tell (env, (RemixBase *)output); n = remix_stream_copy (env, input, output, n); remix_seek (env, (RemixBase *)gi->_gain_envstream, 0, SEEK_SET); n = remix_process (env, gain_envelope, n, RemixNone, gi->_gain_envstream); remix_seek (env, (RemixBase *)gi->_gain_envstream, 0, SEEK_SET); remix_seek (env, (RemixBase *)output, output_offset, SEEK_SET); n = remix_stream_mult (env, gi->_gain_envstream, output, n); remaining -= n; processed += n; } remix_dprintf ("[remix_gain_process] processed %ld\n", processed); return processed; }
static RemixBase * remix_sndfile_create (RemixEnv * env, RemixBase * sndfile, const char * path, int writing) { RemixSndfileInstance * si = remix_malloc (sizeof (struct _RemixSndfileInstance)); si->path = strdup (path); si->writing = writing; if (writing) { si->info.samplerate = remix_get_samplerate (env); si->info.channels = 1; /* XXX: how many channels, or specify? */ si->info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16; /* XXX: assumes WAV */ si->file = sf_open (path, SFM_WRITE, &si->info); si->pcm = NULL; si->pcm_n = 0; } else { si->file = sf_open (path, SFM_READ, &si->info); si->pcm = (float *) malloc (BLOCK_FRAMES * si->info.channels * sizeof(float)); si->pcm_n = 0; } if (si->file == NULL) { remix_set_error (env, REMIX_ERROR_SYSTEM); remix_destroy (env, (RemixBase *)sndfile); return RemixNone; } sf_command (si->file, SFC_SET_NORM_FLOAT, NULL, SF_TRUE); if (writing) sf_command (si->file, SFC_SET_ADD_DITHER_ON_WRITE, NULL, SF_TRUE); sndfile->instance_data = si; return sndfile; }