Permalink
Browse files

working and broken again

  • Loading branch information...
1 parent bca34f8 commit cf3bb7909165c187ecba3d50aeccfb679919be1c @yaxu yaxu committed Feb 17, 2012
Showing with 236 additions and 80 deletions.
  1. +4 −1 Makefile
  2. +157 −52 audio.c
  3. +6 −6 audio.h
  4. +8 −6 file.c
  5. +1 −0 file.h
  6. +9 −5 jack.c
  7. +3 −1 jack.h
  8. +25 −4 segment.c
  9. +5 −4 server.c
  10. +18 −1 test.c
View
@@ -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);
Oops, something went wrong.

0 comments on commit cf3bb79

Please sign in to comment.