Skip to content

Instantly share code, notes, and snippets.

@VienosNotes
Created March 13, 2012 16:08
Show Gist options
  • Select an option

  • Save VienosNotes/2029621 to your computer and use it in GitHub Desktop.

Select an option

Save VienosNotes/2029621 to your computer and use it in GitHub Desktop.
LibSoX for Ruby
#include <sox.h>
#include "ruby.h"
#include <stdlib.h>
#include <assert.h>
typedef struct sox_target {
sox_format_t * in;
sox_format_t * out;
sox_effects_chain_t * chain;
} sox_target_t;
static VALUE rb_cSoX;
void Init_SoX(void);
VALUE new(VALUE);
VALUE libsox_init(VALUE, VALUE, VALUE);
sox_format_t * _sox_read(char *);
sox_format_t * _sox_write(char *, sox_format_t *);
int _sox_create_chain(sox_target_t *);
VALUE libsox_add_effect(int, VALUE*,VALUE);
int _sox_add_effect_internal(sox_target_t *, char *, int, char **);
VALUE libsox_apply_effects(int, VALUE*, VALUE);
VALUE libsox_quit(VALUE);
void Init_SoX(void) {
rb_cSoX = rb_define_class("SoX", rb_cObject);
rb_define_method(rb_cSoX, "initialize", new, 0);
rb_define_method(rb_cSoX, "init", libsox_init, 2);
rb_define_method(rb_cSoX, "add_effect", libsox_add_effect, -1);
rb_define_method(rb_cSoX, "apply", libsox_apply_effects, -1);
rb_define_method(rb_cSoX, "quit", libsox_quit, 0);
}
VALUE new(VALUE self) {
sox_target_t* target;
return Data_Make_Struct(rb_cSoX, sox_target_t, 0, 0, target);
}
VALUE libsox_init(VALUE self, VALUE in_name, VALUE out_name) {
sox_target_t * target = malloc(sizeof(sox_target_t));
sox_format_init();
assert(target->in = _sox_read(StringValuePtr(in_name)));
assert(target->out = _sox_write(StringValuePtr(out_name), target->in));
assert(_sox_create_chain(target) == SOX_SUCCESS);
char * options[10];
options[0] = (char *)target->in;
assert(_sox_add_effect_internal(target, "input", 1, options) == SOX_SUCCESS);
return Data_Wrap_Struct(rb_cSoX,0,0,target);
}
sox_format_t * _sox_read(char * filename) {
sox_format_t * in;
assert(in = sox_open_read(filename, NULL, NULL, NULL));
return in;
}
sox_format_t * _sox_write(char * filename, sox_format_t * in) {
sox_format_t * out;
assert(out = sox_open_write(filename, &in->signal, NULL, NULL, NULL, NULL));
return out;
}
int _sox_create_chain(sox_target_t * target) {
assert(target->chain = sox_create_effects_chain(&target->in->encoding, &target->out->encoding));
return SOX_SUCCESS;
}
VALUE libsox_add_effect(int argc, VALUE *argv, VALUE self) {
sox_target_t * target;
sox_effect_t *e;
char **options = malloc(sizeof(char*) * argc);
Data_Get_Struct(self, sox_target_t, target);
for (int i = 0; i < argc-1; ++i) {
options[i] = RSTRING_PTR(argv[i + 1]);
}
assert(e = sox_create_effect(sox_find_effect(RSTRING_PTR(argv[0]))));
assert((sox_effect_options(e, argc-1, options)) == SOX_SUCCESS);
assert(sox_add_effect(target->chain, e, &target->in->signal, &target->in->signal) == SOX_SUCCESS);
free(e);
free(options);
return INT2FIX(SOX_SUCCESS);
}
int _sox_add_effect_internal(sox_target_t *target, char *name, int count,char **options) {
sox_effect_t *e;
assert(e = sox_create_effect(sox_find_effect(name)));
assert(sox_effect_options(e, count, options) == SOX_SUCCESS);
assert(sox_add_effect(target->chain, e, &target->in->signal, &target->in->signal) == SOX_SUCCESS);
free(e);
return SOX_SUCCESS;
}
VALUE libsox_apply_effects(int argc, VALUE *argv, VALUE self) {
sox_target_t * target;
Data_Get_Struct(self, sox_target_t, target);
char * options[1];
options[0] = (char *)target->out;
assert(_sox_add_effect_internal(target, "output", 1, options) == SOX_SUCCESS);
sox_flow_effects(target->chain, NULL, NULL);
return INT2FIX(SOX_SUCCESS);
}
VALUE libsox_quit(VALUE self) {
sox_target_t * target;
Data_Get_Struct(self, sox_target_t, target);
sox_delete_effects_chain(target->chain);
sox_close(target->out);
sox_close(target->in);
// sox_quit();
return INT2FIX(SOX_SUCCESS);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment