Skip to content

Commit

Permalink
there
Browse files Browse the repository at this point in the history
  • Loading branch information
yaxu committed Feb 9, 2012
1 parent 1c8a7a2 commit ab0fe60
Show file tree
Hide file tree
Showing 9 changed files with 381 additions and 0 deletions.
11 changes: 11 additions & 0 deletions Makefile
@@ -0,0 +1,11 @@
CC=gcc
CFLAGS = -O3 -g -Wall -pedantic
LDFLAGS = -llo -lsndfile -lsamplerate -ljack

all: dirt

clean :
rm -f *.o *~ dirt

dirt: dirt.o jack.o audio.o file.o Makefile
$(CC) dirt.o jack.o audio.o file.o $(CFLAGS) $(LDFLAGS) -o dirt
8 changes: 8 additions & 0 deletions audio.c
@@ -0,0 +1,8 @@

extern int audio_callback(int samples, float *buffer) {
int i;
for (i=0; i < samples; ++i) {
buffer[0] = 0;
}
return(0);
}
2 changes: 2 additions & 0 deletions audio.h
@@ -0,0 +1,2 @@

extern int audio_callback(int samples, float *buffer);
13 changes: 13 additions & 0 deletions dirt.c
@@ -0,0 +1,13 @@
#include <stdio.h>

#include <unistd.h>

#include "jack.h"
#include "audio.h"

int main (int argc, char **argv) {
int samplerate = jack_start(audio_callback);

sleep(-1);
return(0);
}
125 changes: 125 additions & 0 deletions file.c
@@ -0,0 +1,125 @@
#include <sndfile.h>
#include <samplerate.h>
#include <string.h>
#include <dirent.h>
#include <stdlib.h>

#include "file.h"

t_sample *samples[MAXSAMPLES];
int sample_count = 0;


t_sample *find_sample (char *samplename) {
int c;
t_sample *sample = NULL;

for(c = 0; c < sample_count; ++c) {
if(strcmp(samples[c]->name, samplename) == 0) {
sample = samples[c];
break;
}
}
return(sample);
}

int wav_filter (const struct dirent *d) {
if (strlen(d->d_name) > 4) {
printf("%s\n", d->d_name + strlen(d->d_name) - 4);
return(strcmp(d->d_name + strlen(d->d_name) - 4, ".wav") == 0);
}
return(0);
}

void fix_samplerate (t_sample *sample, int samplerate) {
SRC_DATA data;
int max_output_frames;
int channels = sample->info->channels;

data.src_ratio = sample->info->samplerate / samplerate;

max_output_frames = sample->info->frames * data.src_ratio + 32;

data.data_in = sample->frames;
data.input_frames = sample->info->frames;

data.data_out = (float *) malloc(sizeof(float)
* max_output_frames
* channels
);
data.output_frames = max_output_frames;

src_simple(&data, SRC_SINC_BEST_QUALITY, channels);

sample->frames = data.data_out;
sample->info->samplerate = samplerate;
sample->info->frames = data.output_frames_gen;
}

t_sample *get_sample(char *samplename, int samplerate) {
SNDFILE *sndfile;
char path[MAXPATHSIZE];
char error[62];
t_sample *sample;
sf_count_t count;
float *frames;
SF_INFO *info;
char set[MAXPATHSIZE];
int set_n = 0;
struct dirent **namelist;

sample = find_sample(samplename);

if (sample == NULL) {
/* load it from disk */
if (sscanf(samplename, "%[a-z0-9A-Z]/%d", set, &set_n)) {
int n;
snprintf(path, MAXPATHSIZE -1, "%s/%s", SAMPLEROOT, set);
n = scandir(path, &namelist, wav_filter, alphasort);
if (n > 0) {
snprintf(path, MAXPATHSIZE -1,
"%s/%s/%s", SAMPLEROOT, set, namelist[set_n % n]->d_name);
while (n--) {
free(namelist[n]);
}
free(namelist);
}
else {
path[0] = '\0';
}
}
else {
snprintf(path, MAXPATHSIZE -1, "%s/%s", SAMPLEROOT, samplename);
}
info = (SF_INFO *) calloc(1, sizeof(SF_INFO));

if ((sndfile = (SNDFILE *) sf_open(path, SFM_READ, info)) == NULL) {
free(info);
}
else {
frames = (float *) malloc(sizeof(float) * info->frames);
snprintf(error, (size_t) 61, "hm: %d\n", sf_error(sndfile));
perror(error);
count = sf_read_float(sndfile, frames, info->frames);
snprintf(error, (size_t) 61, "hmm: %d vs %d %d\n", (int) count, (int) info->frames, sf_error(sndfile));
perror(error);

if (count == info->frames) {
sample = (t_sample *) calloc(1, sizeof(t_sample));
strncpy(sample->name, samplename, MAXPATHSIZE - 1);
sample->info = info;
sample->frames = frames;
samples[sample_count++] = sample;
}
else {
snprintf(error, (size_t) 61, "didn't get the right number of frames: %d vs %d %d\n", (int) count, (int) info->frames, sf_error(sndfile));
perror(error);
free(info);
free(frames);
}
}
fix_samplerate(sample, samplerate);
}

return(sample);
}
12 changes: 12 additions & 0 deletions file.h
@@ -0,0 +1,12 @@

#define MAXSAMPLES 1024
#define MAXFILES 4096
#define MAXPATHSIZE 256

#define SAMPLEROOT "./"

typedef struct {
char name[MAXPATHSIZE];
SF_INFO *info;
float *frames;
} t_sample;
90 changes: 90 additions & 0 deletions jack.c
@@ -0,0 +1,90 @@
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

#include <jack/jack.h>

#include "jack.h"

jack_port_t *output_port;
jack_client_t *client;

int process(jack_nframes_t nframes, void *arg) {
jack_default_audio_sample_t *out;
t_callback callback = (t_callback) arg;

out = jack_port_get_buffer(output_port, nframes);
callback(nframes, out);

return 0;
}

void jack_shutdown(void *arg) {
exit(1);
}

extern int jack_start(t_callback callback) {
const char **ports;
const char *client_name = "dirt";
const char *server_name = NULL;
jack_options_t options = JackNullOption;
jack_status_t status;

/* open a client connection to the JACK server */

client = jack_client_open(client_name, options, &status, server_name);
if (client == NULL) {
fprintf(stderr, "jack_client_open() failed, "
"status = 0x%2.0x\n", status);
if (status & JackServerFailed) {
fprintf(stderr, "Unable to connect to JACK server\n");
}
exit(1);
}
if (status & JackServerStarted) {
fprintf(stderr, "JACK server started\n");
}
if (status & JackNameNotUnique) {
client_name = jack_get_client_name(client);
fprintf(stderr, "unique name `%s' assigned\n", client_name);
}

jack_set_process_callback(client, process, callback);

jack_on_shutdown(client, jack_shutdown, 0);

printf("engine sample rate: %" PRIu32 "\n",
jack_get_sample_rate(client));

output_port = jack_port_register(client, "output",
JACK_DEFAULT_AUDIO_TYPE,
JackPortIsOutput, 0);

if (output_port == NULL) {
fprintf(stderr, "no more JACK ports available\n");
exit(1);
}

if (jack_activate(client)) {
fprintf(stderr, "cannot activate client");
exit(1);
}

ports = jack_get_ports(client, NULL, NULL,
JackPortIsPhysical|JackPortIsInput);
if (ports == NULL) {
fprintf(stderr, "no physical playback ports\n");
exit(1);
}

if (jack_connect(client, jack_port_name(output_port), ports[0])) {
fprintf(stderr, "cannot connect output ports\n");
}

free(ports);

return(jack_get_sample_rate(client));
}

4 changes: 4 additions & 0 deletions jack.h
@@ -0,0 +1,4 @@


typedef int (*t_callback)(int, float *);
extern int jack_start(t_callback callback);
116 changes: 116 additions & 0 deletions server.c
@@ -0,0 +1,116 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <lo/lo.h>

#include "server.h"

void error(int num, const char *m, const char *path);

int trigger_handler(const char *path, const char *types, lo_arg **argv,
int argc, void *data, void *user_data);

int generic_handler(const char *path, const char *types, lo_arg **argv,
int argc, void *data, void *user_data);

/**/

extern int server_init(void) {
lo_server_thread st = lo_server_thread_new("7771", error);

#ifdef DEBUG
lo_server_thread_add_method(st, NULL, NULL, generic_handler, NULL);
#endif

lo_server_thread_add_method(st, "/trigger", "sfffffsfffssffffff",
trigger_handler,
NULL
);
lo_server_thread_start(st);

return(1);
}

/**/

void error(int num, const char *msg, const char *path) {
printf("liblo server error %d in path %s: %s\n", num, path, msg);
}

/**/

int generic_handler(const char *path, const char *types, lo_arg **argv,
int argc, void *data, void *user_data)
{
int i;

printf("path: <%s>\n", path);
for (i=0; i<argc; i++) {
printf("arg %d '%c' ", i, types[i]);
lo_arg_pp(types[i], argv[i]);
printf("\n");
}
printf("\n");

return 1;
}

/**/

int trigger_handler(const char *path, const char *types, lo_arg **argv,
int argc, void *data, void *user_data) {

lo_timetag ts = lo_message_get_timestamp(data);

char *sample_name = strdup((char *) argv[0]);
float speed = argv[1]->f;
float shape = argv[2]->f;
float pan = argv[3]->f;
float pan_to = argv[4]->f;
float volume = argv[5]->f;
char *envelope_name = strdup((char *) argv[6]);
float anafeel_strength = argv[7]->f;
float anafeel_frequency = argv[8]->f;
float accellerate = argv[9]->f;
char *vowel_s = (char *) argv[10];
char *scale_name = strdup((char *) argv[11]);
float loops = argv[12]->f;
float duration = argv[13]->f;
float delay = argv[14]->f;
float delay2 = argv[15]->f;
float cutoff = argv[16]->f;
float resonance = argv[17]->f;

int vowel = -1;
switch(vowel_s[0]) {
case 'a': case 'A': vowel = 0; break;
case 'e': case 'E': vowel = 1; break;
case 'i': case 'I': vowel = 2; break;
case 'o': case 'O': vowel = 3; break;
case 'u': case 'U': vowel = 4; break;
}

audio_trigger(ts,
sample_name,
speed,
shape,
pan,
pan_to,
volume,
envelope_name,
anafeel_strength,
anafeel_frequency,
accellerate,
vowel,
scale_name,
loops,
duration,
delay,
delay2,
cutoff,
resonance
);
return 0;
}

0 comments on commit ab0fe60

Please sign in to comment.