Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

working and broken again

  • Loading branch information...
commit cf3bb7909165c187ecba3d50aeccfb679919be1c 1 parent bca34f8
@yaxu yaxu authored
View
5 Makefile
@@ -1,6 +1,6 @@
CC=gcc
# -O3
-CFLAGS = -g -Wall -pedantic
+CFLAGS = -g -Wall
LDFLAGS = -llo -lsndfile -lsamplerate -ljack -laubio
all: dirt
@@ -10,3 +10,6 @@ clean:
dirt: dirt.o jack.o audio.o file.o server.o segment.o Makefile
$(CC) dirt.o jack.o audio.o file.o server.o segment.o $(CFLAGS) $(LDFLAGS) -o dirt
+
+test : test.c Makefile
+ $(CC) test.c -llo -o test
View
209 audio.c
@@ -3,11 +3,13 @@
#include <string.h>
#include <sys/time.h>
#include <jack/jack.h>
+#include <math.h>
+#include <assert.h>
#include "jack.h"
#include "audio.h"
-pthread_mutex_t queue_lock;
+pthread_mutex_t queue_waiting_lock;
t_queue *waiting = NULL;
t_queue *playing = NULL;
@@ -19,120 +21,223 @@ jack_client_t *client = NULL;
extern void audio_init(void) {
int samplerate;
- pthread_mutex_init(&queue_lock, NULL);
+ pthread_mutex_init(&queue_waiting_lock, NULL);
client = jack_start(audio_callback);
samplerate = jack_get_sample_rate(client);
file_set_samplerate(samplerate);
}
-void queue_add(t_queue *queue, t_queue *new) {
- if (queue == NULL) {
- queue = new;
+int queue_size(t_queue *queue) {
+ int result = 0;
+ while (queue != NULL) {
+ result++;
+ queue = queue->next;
+ if (result > 1024) {
+ printf("whoops, big queue\n");
+ break;
+ }
+ }
+ return(result);
+}
+
+void queue_add(t_queue **queue, t_queue *new) {
+ //printf("queuing %s @ %lld\n", new->sound->samplename, new->start);
+ int s = queue_size(*queue);
+ int added = 0;
+ if (*queue == NULL) {
+ *queue = new;
+ assert(s == (queue_size(*queue) - 1));
+ added++;
}
else {
- t_queue *tmp = queue;
- while (1) {
- if (tmp->next == NULL) {
- tmp->next = new;
- new->last = tmp;
- break;
- }
+ t_queue *tmp = *queue;
+ assert(tmp->prev == NULL);
- if (tmp->when > new->when) {
+ int i =0;
+ while (1) {
+ if (tmp->start > new->start) {
+ // insert in front of later event
new->next = tmp;
- new->last = tmp->last;
- if (tmp->last) {
- tmp->last->next = new;
- tmp->last = new;
+ new->prev = tmp->prev;
+ if (new->prev != NULL) {
+ new->prev->next = new;
+ }
+ else {
+ *queue = new;
}
+ tmp->prev = new;
- if (queue == tmp) {
- queue = new;
+ if (s != (queue_size(*queue) - 1)) {
+ assert(s == (queue_size(*queue) - 1));
}
+ added++;
break;
}
+ if (tmp->next == NULL) {
+ // add to end of queue
+ tmp->next = new;
+ new->prev = tmp;
+ added++;
+ assert(s == (queue_size(*queue) - 1));
+ break;
+ }
+ ++i;
tmp = tmp->next;
}
}
-}
-void queue_remove(t_queue *queue, t_queue *old) {
- if (queue == old) {
- queue = old->next;
+ if (s != (queue_size(*queue) - added)) {
+ assert(s == (queue_size(*queue) - added));
}
- if (old->last) {
- old->last->next = old->next;
+ assert(added == 1);
+}
+
+
+void queue_remove(t_queue **queue, t_queue *old) {
+ int s = queue_size(*queue);
+ if (old->prev == NULL) {
+ *queue = old->next;
+ if (*queue != NULL) {
+ (*queue)->prev = NULL;
+ }
}
- if (old->next) {
- old->next->last = old->last;
+ else {
+ old->prev->next = old->next;
+
+ if (old->next) {
+ old->next->prev = old->prev;
+ }
}
- free(old);
+ assert(s == (queue_size(*queue) + 1));
+ //free(old);
}
-extern int audio_play(char *samplename) {
+extern int audio_play(double when, char *samplename) {
int result = 0;
t_sound *sound;
t_sample *sample = file_get(samplename);
-
+ //printf("samplename: %s when: %f\n", samplename, when);
if (sample != NULL) {
+ //printf("got\n");
t_queue *new;
- sound = (t_sound *) malloc(sizeof(t_sound));
+ sound = (t_sound *) calloc(1, sizeof(t_sound));
strncpy(sound->samplename, samplename, MAXPATHSIZE);
sound->sample = sample;
- new = (t_queue *) malloc(sizeof(t_queue));
- new->when = -1;
+ new = (t_queue *) calloc(1, sizeof(t_queue));
+ new->start = jack_time_to_frames(client, ((when-offset) * 1000000));
+ //printf("start: %lld\n", new->start);
new->sound = sound;
new->next = NULL;
- new->last = NULL;
+ new->prev = NULL;
new->position = 0;
new->speed = 1;
- pthread_mutex_lock(&queue_lock);
- queue_add(waiting, new);
- pthread_mutex_unlock(&queue_lock);
+ pthread_mutex_lock(&queue_waiting_lock);
+ queue_add(&waiting, new);
+ //printf("added: %d\n", waiting != NULL);
+ pthread_mutex_unlock(&queue_waiting_lock);
result = 1;
}
return(result);
}
-t_queue *queue_next(t_queue *queue, double now) {
+t_queue *queue_next(t_queue **queue, jack_nframes_t now) {
t_queue *result = NULL;
- if (queue != NULL && queue->when <= now) {
- result = queue;
- queue = queue->next;
+ if (*queue != NULL && (*queue)->start <= now) {
+ result = *queue;
+ *queue = (*queue)->next;
+ if ((*queue) != NULL) {
+ (*queue)->prev = NULL;
+ }
}
+
+ if (*queue != NULL && (*queue)->start > now) {
+ //printf("diff %f - %f = %f\n", *queue->start, now, *queue->start - now);
+ }
+
return(result);
}
-void dequeue() {
+void dequeue(jack_nframes_t now) {
t_queue *p;
- while (p = queue_next(waiting, now) != NULL) {
- p->last = NULL;
+ pthread_mutex_lock(&queue_waiting_lock);
+ while ((p = queue_next(&waiting, now)) != NULL) {
+ int s = queue_size(playing);
+ //printf("dequeuing %s @ %d\n", p->sound->samplename, p->start);
+ p->prev = NULL;
p->next = playing;
if (playing != NULL) {
- playing->last = p;
+ playing->prev = p;
}
playing = p;
+ assert(s == (queue_size(playing) - 1));
+
+ //printf("done.\n");
}
+ pthread_mutex_unlock(&queue_waiting_lock);
}
-extern int audio_callback(int frames, float *buffer) {
+
+inline void playback(float **buffers, int frame, jack_nframes_t frametime) {
+ int channel;
+ t_queue *p = playing;
+
+ for (channel = 0; channel < CHANNELS; ++channel) {
+ buffers[channel][frame] = 0;
+ }
+ //printf("ah\n");
+ while (p != NULL) {
+ int channels;
+ t_queue *tmp;
+ //printf("compare start %d with frametime %d\n", p->start, frametime);
+ if (p->start > frametime) {
+ p = p->next;
+ continue;
+ }
+ //printf("playing %s\n", p->sound->samplename);
+ channels = p->sound->sample->info->channels;
+ //printf("channels: %d\n", channels);
+ for (channel = 0; channel < channels; ++channel) {
+ /* todo tween */
+ buffers[channel][frame] +=
+ p->sound->sample->frames[(channels * ((int) p->position)) + channel];
+ }
+
+ p->position += p->speed;
+ //printf("position: %d of %d\n", p->position, playing->sound->sample->info->frames);
+
+ /* remove dead sounds */
+ tmp = p;
+ p = p->next;
+ if (tmp->position >= tmp->sound->sample->info->frames) {
+ //printf("remove %s\n", tmp->sound->samplename);
+ queue_remove(&playing, tmp);
+ }
+ }
+}
+
+extern int audio_callback(int frames, float **buffers) {
int i;
+ jack_nframes_t now;
+
if (offset == 0) {
struct timeval tv;
gettimeofday(&tv, NULL);
- offset = (tv.sec + (tv.usec / 1000000)) - jack_get_time();
+ offset = ((double) tv.tv_sec + ((double) tv.tv_usec / 1000000.0))
+ - ((double) jack_get_time() / 1000000.0);
+ //printf("jack time: %d tv_sec %d offset: %f\n", jack_get_time(), tv.tv_sec, offset);
}
-
+
+ now = jack_last_frame_time(client);
+
for (i=0; i < frames; ++i) {
- pthread_mutex_lock(&queue_lock);
- dequeue();
- pthread_mutex_unlock(&queue_lock);
- buffer[0] = playback();
+ dequeue(now + frames);
+
+ playback(buffers, i, now + i);
}
return(0);
}
View
12 audio.h
@@ -1,20 +1,20 @@
+#include <jack/jack.h>
#include "file.h"
typedef struct {
char samplename[MAXPATHSIZE+1];
t_sample *sample;
- double position;
- double speed;
} t_sound;
typedef struct t_node {
- double when;
+ jack_nframes_t start;
t_sound *sound;
- struct t_node *next, *last;
+ struct t_node *next, *prev;
double position;
+ double speed;
} t_queue;
-extern int audio_callback(int samples, float *buffer);
+extern int audio_callback(int frames, float **buffers);
extern void audio_init(void);
-extern int audio_play(char *samplename);
+extern int audio_play(double when, char *samplename);
View
14 file.c
@@ -5,6 +5,7 @@
#include <stdlib.h>
#include "file.h"
+#include "segment.h"
t_sample *samples[MAXSAMPLES];
int sample_count = 0;
@@ -45,11 +46,10 @@ void fix_samplerate (t_sample *sample) {
max_output_frames = sample->info->frames * data.src_ratio + 32;
data.data_in = sample->frames;
- data.input_frames = sample->info->frames;
+ data.input_frames = sample->info->frames / channels;
- data.data_out = (float *) malloc(sizeof(float)
- * max_output_frames
- * channels
+ data.data_out = (float *) calloc(1, sizeof(float)
+ * max_output_frames
);
data.output_frames = max_output_frames;
@@ -58,6 +58,7 @@ void fix_samplerate (t_sample *sample) {
sample->frames = data.data_out;
sample->info->samplerate = samplerate;
sample->info->frames = data.output_frames_gen;
+
}
extern t_sample *file_get(char *samplename) {
@@ -72,7 +73,7 @@ extern t_sample *file_get(char *samplename) {
int set_n = 0;
struct dirent **namelist;
- printf("find %s\n", samplename);
+ //printf("find %s\n", samplename);
sample = find_sample(samplename);
if (sample == NULL) {
@@ -102,7 +103,7 @@ extern t_sample *file_get(char *samplename) {
free(info);
}
else {
- frames = (float *) malloc(sizeof(float) * info->frames);
+ frames = (float *) calloc(1, 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);
@@ -128,6 +129,7 @@ extern t_sample *file_get(char *samplename) {
}
else {
fix_samplerate(sample);
+ sample->onsets = segment_get_onsets(sample);
}
}
View
1  file.h
@@ -10,6 +10,7 @@ typedef struct {
char name[MAXPATHSIZE];
SF_INFO *info;
float *frames;
+ int *onsets;
} t_sample;
extern void file_set_samplerate(int s);
View
14 jack.c
@@ -9,13 +9,17 @@
#include "jack.h"
jack_client_t *client;
-jack_port_t output_ports[CHANNELS+1];
+jack_port_t *output_ports[CHANNELS+1];
int process(jack_nframes_t nframes, void *arg) {
- jack_default_audio_sample_t *out;
+ jack_default_audio_sample_t *out[CHANNELS+1];
t_callback callback = (t_callback) arg;
+ int i;
- out = jack_port_get_buffer(output_ports, nframes);
+ for (i = 0; i < CHANNELS; ++i) {
+ out[i] = jack_port_get_buffer(output_ports[i], nframes);
+ }
+
callback(nframes, out);
return 0;
@@ -62,7 +66,7 @@ extern jack_client_t *jack_start(t_callback callback) {
printf("engine sample rate: %" PRIu32 "\n",
jack_get_sample_rate(client));
- for (int i = 0; i < CHANNELS; ++i) {
+ for (i = 0; i < CHANNELS; ++i) {
sprintf(portname, "output_%d", i);
output_ports[i] = jack_port_register(client, portname,
JACK_DEFAULT_AUDIO_TYPE,
@@ -81,7 +85,7 @@ extern jack_client_t *jack_start(t_callback callback) {
ports = jack_get_ports(client, NULL, NULL,
JackPortIsPhysical|JackPortIsInput);
- for (int i = 0; i < CHANNELS; ++i) {
+ for (i = 0; i < CHANNELS; ++i) {
if (ports[i] == NULL) {
break;
}
View
4 jack.h
@@ -1,6 +1,8 @@
+#include <jack/jack.h>
+
#define CHANNELS 2
-typedef int (*t_callback)(int, float *);
+typedef int (*t_callback)(int, float **);
extern jack_client_t *jack_start(t_callback callback);
View
29 segment.c
@@ -1,4 +1,8 @@
+#include <stdlib.h>
+#include <string.h>
+#include <sndfile.h>
#include <aubio/aubio.h>
+#include "file.h"
int overlap_size = 256;
aubio_pvoc_t * pv;
@@ -41,17 +45,20 @@ void aubio_destruct() {
del_fvec(onset);
}
-int aubio_process(float *input, int nframes) {
+int *aubio_process(t_sample *sound, float *input, sf_count_t nframes) {
unsigned int j, i; /*frames*/
- for (j=0;j<(unsigned)nframes;j++) {
+ int *result;
+ int actual_frames = nframes / channels;
+
+ for (j=0; j < actual_frames; j++) {
for (i=0; i < channels; i++) {
/* write input to datanew */
fvec_write_sample(ibuf, input[channels*j+i], i, pos);
}
}
- for (j=0;j<(unsigned)nframes;j++) {
+ for (j=0; j < actual_frames; j++) {
/*time for fft*/
if ((pos % (overlap_size-1)) == 0) {
int isonset;
@@ -77,5 +84,19 @@ int aubio_process(float *input, int nframes) {
}
pos++;
}
- return 1;
+
+ result = (int *) calloc(1, sizeof(unsigned int) * (onset_n + 1));
+ memcpy(result, onsets, sizeof(int) * onset_n);
+ result[onset_n] = -1;
+ printf("found %d onsets\n", onset_n);
+
+ return(result);
+}
+
+extern int *segment_get_onsets(t_sample *sound) {
+ int *result;
+ aubio_init(sound->info->channels);
+ result = aubio_process(sound, sound->frames, sound->info->frames);
+ aubio_destruct();
+ return(result);
}
View
9 server.c
@@ -45,9 +45,10 @@ int play_handler(const char *path, const char *types, lo_arg **argv,
/* lo_timetag ts = lo_message_get_timestamp(data); */
- char *sample_name = strdup((char *) argv[0]);
+ double when = (double) argv[0]->d + ((double) argv[1]->d / 1000000.0);
+ char *sample_name = strdup((char *) argv[2]);
- audio_play(//ts,
+ audio_play(when,
sample_name
);
return 0;
@@ -58,9 +59,9 @@ int play_handler(const char *path, const char *types, lo_arg **argv,
extern int server_init(void) {
lo_server_thread st = lo_server_thread_new("7771", error);
- lo_server_thread_add_method(st, NULL, NULL, generic_handler, NULL);
+ //lo_server_thread_add_method(st, NULL, NULL, generic_handler, NULL);
- lo_server_thread_add_method(st, "/play", "s",
+ lo_server_thread_add_method(st, "/play", "dds",
play_handler,
NULL
);
View
19 test.c
@@ -2,11 +2,28 @@
#include <stdlib.h>
#include <unistd.h>
#include <lo/lo.h>
+#include <time.h>
+
+#define STRENGTH 64
int main(int argc, char *argv[]) {
lo_address t = lo_address_new(NULL, "7771");
+ int result;
+ int i;
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ lo_send(t, "/play", "iis", tv.tv_sec, tv.tv_usec, "tabla/0");
+
+ /* for(i = 0; i < STRENGTH; ++i) {
+ tv.tv_usec += 8000 + 100 * i;
- int result = lo_send(t, "/play", "s", "drum/0");
+ while (tv.tv_usec > 1000000) {
+ tv.tv_usec -= 1000000;
+ tv.tv_sec++;
+ }
+ result = lo_send(t, "/play", "iis", tv.tv_sec, tv.tv_usec, "chin/0");
+ }
+ */
printf("result: %d\n", result);
return(0);
Please sign in to comment.
Something went wrong with that request. Please try again.