Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'master' of github.com:yaxu/Dirt

Conflicts:
	audio.h
  • Loading branch information...
commit ba21e71f4d4d85c7fdc5b2e9cb4f99514d48e7b8 2 parents 022fb70 + fb7aa5b
alex authored
View
175 audio.c
@@ -6,6 +6,7 @@
#include <math.h>
#include <assert.h>
+#include "config.h"
#include "jack.h"
#include "audio.h"
@@ -16,17 +17,23 @@ pthread_mutex_t queue_waiting_lock;
t_sound *waiting = NULL;
t_sound *playing = NULL;
+#ifdef FEEDBACK
+t_loop *loop = NULL;
+#endif
+
double epochOffset = 0;
jack_client_t *client = NULL;
+static int samplerate = 0;
extern void audio_init(void) {
- int samplerate;
-
pthread_mutex_init(&queue_waiting_lock, NULL);
client = jack_start(audio_callback);
samplerate = jack_get_sample_rate(client);
file_set_samplerate(samplerate);
+#ifdef FEEDBACK
+ loop = new_loop(8);
+#endif
}
int queue_size(t_sound *queue) {
@@ -167,58 +174,91 @@ float formant_filter(float in, t_sound *sound, int channel) {
}
extern int audio_play(double when, char *samplename, float offset, float start, float end, float speed, float pan, float velocity, int vowelnum) {
- int result = 0;
struct timeval tv;
- t_sample *sample = file_get(samplename);
-
+#ifdef FEEDBACK
+ int is_loop = 0;
+#endif
+ t_sample *sample = NULL;
+ t_sound *new;
+
gettimeofday(&tv, NULL);
- //printf("samplename: %s when: %f\n", samplename, when - (float) tv.tv_sec);
- if (sample != NULL) {
- //printf("got\n");
- t_sound *new = (t_sound *) calloc(1, sizeof(t_sound));
-
- strncpy(new->samplename, samplename, MAXPATHSIZE);
- new->sample = sample;
- new->startFrame =
- jack_time_to_frames(client, ((when-epochOffset) * 1000000));
- //printf("start: %lld\n", new->start);
- new->next = NULL;
- new->prev = NULL;
- new->startframe = 0;
- new->speed = speed;
- new->pan = pan;
- new->velocity = velocity;
-
- new->offset = offset;
- new->frames = new->sample->info->frames;
-
- if (start > 0 && start <= 1) {
- new->startframe = start * new->frames;
- }
-
- if (end > 0 && end < 1) {
- new->frames *= end;
- }
- if (new->speed == 0) {
- new->speed = 1;
- }
-
- if (new->speed < 0) {
- new->startframe = new->frames - new->startframe;
- }
- new->position = new->startframe;
- new->formant_vowelnum = vowelnum;
+#ifdef FEEDBACK
+ if (strcmp(samplename, "loop") == 0) {
+ is_loop = 1;
+ }
+ else {
+#endif
+ sample = file_get(samplename);
+ if (sample == NULL) {
+ return(0);
+ }
+#ifdef FEEDBACK
+ }
+#endif
+
+ new = (t_sound *) calloc(1, sizeof(t_sound));
+ printf("samplename: %s when: %f\n", samplename, when - (float) tv.tv_sec);
+ strncpy(new->samplename, samplename, MAXPATHSIZE);
+
+#ifdef FEEDBACK
+ if (is_loop) {
+ new->loop = loop;
+ new->frames = loop->frames;
+ new->items = loop->items;
+ new->channels = 1;
+ new->loop_start = (loop->now + (loop->frames / 2)) % loop->frames;
+ }
+ else {
+#endif
+ new->sample = sample;
+ new->frames = sample->info->frames;
+ new->items = sample->items;
+ new->channels = sample->info->channels;
+#ifdef FEEDBACK
+ }
+ new->is_loop = is_loop;
+#endif
- pthread_mutex_lock(&queue_waiting_lock);
- queue_add(&waiting, new);
- //printf("added: %d\n", waiting != NULL);
- pthread_mutex_unlock(&queue_waiting_lock);
+ new->startFrame =
+ jack_time_to_frames(client, ((when-epochOffset) * 1000000));
+
+ new->next = NULL;
+ new->prev = NULL;
+ new->startframe = 0;
+ new->speed = speed;
+ new->pan = pan;
+ new->velocity = velocity;
+
+ new->offset = offset;
- result = 1;
+ printf("frames: %f\n", new->frames);
+ if (start > 0 && start <= 1) {
+ new->startframe = start * new->frames;
}
- return(result);
+
+ if (end > 0 && end < 1) {
+ new->frames *= end;
+ }
+
+ if (new->speed == 0) {
+ new->speed = 1;
+ }
+
+ if (new->speed < 0) {
+ new->startframe = new->frames - new->startframe;
+ }
+
+ new->position = new->startframe;
+ new->formant_vowelnum = vowelnum;
+
+ pthread_mutex_lock(&queue_waiting_lock);
+ queue_add(&waiting, new);
+ //printf("added: %d\n", waiting != NULL);
+ pthread_mutex_unlock(&queue_waiting_lock);
+
+ return(1);
}
t_sound *queue_next(t_sound **queue, jack_nframes_t now) {
@@ -272,18 +312,35 @@ inline void playback(float **buffers, int frame, jack_nframes_t frametime) {
continue;
}
//printf("playing %s\n", p->samplename);
- channels = p->sample->info->channels;
+ channels = p->channels;
//printf("channels: %d\n", channels);
for (channel = 0; channel < channels; ++channel) {
float roundoff = 1;
- float value =
- p->sample->items[(channels * ((int) p->position)) + channel];
+ float value;
+
+#ifdef FEEDBACK
+ if (p->is_loop) {
+ // only one channel, but relative to 'now'
+ unsigned int i = (p->loop_start + ((int) p->position)) % p->loop->frames;
+ value = p->items[i];
+ }
+ else {
+#endif
+ value = p->items[(channels * ((int) p->position)) + channel];
+#ifdef FEEDBACK
+ }
+#endif
+
int pos = ((int) p->position) + 1;
+#ifdef FEEDBACK
+ if ((!p->is_loop) && pos < p->frames) {
+#else
if (pos < p->frames) {
+#endif
float next =
- p->sample->items[(channels * pos)
- + channel
- ];
+ p->items[(channels * pos)
+ + channel
+ ];
float tween_amount = (p->position - (int) p->position);
@@ -345,7 +402,7 @@ inline void playback(float **buffers, int frame, jack_nframes_t frametime) {
}
}
-extern int audio_callback(int frames, float **buffers) {
+extern int audio_callback(int frames, float *input, float **outputs) {
int i;
jack_nframes_t now;
@@ -356,13 +413,19 @@ extern int audio_callback(int frames, float **buffers) {
- ((double) jack_get_time() / 1000000.0);
//printf("jack time: %d tv_sec %d epochOffset: %f\n", jack_get_time(), tv.tv_sec, epochOffset);
}
-
now = jack_last_frame_time(client);
for (i=0; i < frames; ++i) {
+#ifdef FEEDBACK
+ loop->items[loop->now++] = input[i];
+
+ if (loop->now >= loop->frames) {
+ loop->now = 0;
+ }
+#endif
dequeue(now + frames);
- playback(buffers, i, now + i);
+ playback(outputs, i, now + i);
}
return(0);
}
View
11 audio.h
@@ -10,7 +10,14 @@
typedef struct t_node {
jack_nframes_t startFrame;
char samplename[MAXPATHSIZE+1];
- t_sample *sample;
+ int is_loop;
+ union {
+ t_sample *sample;
+ t_loop *loop;
+ };
+ unsigned int loop_start;
+ int channels;
+ float *items;
struct t_node *next, *prev;
double position;
float speed;
@@ -23,6 +30,6 @@ typedef struct t_node {
int formant_vowelnum;
} t_sound;
-extern int audio_callback(int frames, float **buffers);
+extern int audio_callback(int frames, float *input, float **outputs);
extern void audio_init(void);
extern int audio_play(double when, char *samplename, float offset, float start, float end, float speed, float pan, float velocity, int vowelnum);
View
2  config.h
@@ -0,0 +1,2 @@
+
+#define FEEDBACK
View
1  dirt.c
@@ -4,6 +4,7 @@
#include "jack.h"
#include "audio.h"
+#include "server.h"
int main (int argc, char **argv) {
printf("init audio\n");
View
24 file.c
@@ -16,6 +16,14 @@ extern void file_set_samplerate(int s) {
samplerate = s;
}
+t_loop *new_loop(float seconds) {
+ t_loop *result = (t_loop *) calloc(1, sizeof(t_loop));
+ result->frames = seconds * (float) samplerate;
+ result->items = (float *) calloc(result->frames, sizeof(float));
+ result->now = 0;
+ return(result);
+}
+
t_sample *find_sample (char *samplename) {
int c;
t_sample *sample = NULL;
@@ -43,8 +51,12 @@ void fix_samplerate (t_sample *sample) {
int max_output_frames;
int channels = sample->info->channels;
- data.src_ratio = sample->info->samplerate / samplerate;
-
+ //printf("start frames: %d\n", sample->info->frames);
+ if (sample->info->samplerate == samplerate) {
+ return;
+ }
+ data.src_ratio = (float) samplerate / (float) sample->info->samplerate;
+ //printf("ratio: %d / %d = %f\n", sample->info->samplerate, samplerate, data.src_ratio);
max_output_frames = sample->info->frames * data.src_ratio + 32;
data.data_in = sample->items;
@@ -55,14 +67,14 @@ void fix_samplerate (t_sample *sample) {
* channels
);
data.output_frames = max_output_frames;
-
+
src_simple(&data, SRC_SINC_BEST_QUALITY, channels);
/* TODO - free old items */
sample->items = data.data_out;
sample->info->samplerate = samplerate;
sample->info->frames = data.output_frames_gen;
-
+ //printf("end samplerate: %d frames: %d\n", (int) sample->info->samplerate, sample->info->frames);
}
extern t_sample *file_get(char *samplename) {
@@ -113,8 +125,8 @@ extern t_sample *file_get(char *samplename) {
/*snprintf(error, (size_t) 61, "hm: %d\n", sf_error(sndfile));
perror(error);*/
count = sf_read_float(sndfile, items, info->frames * info->channels);
- /* snprintf(error, (size_t) 61, "hmm: %d vs %d %d\n", (int) count, (int) info->frames, sf_error(sndfile));
- perror(error);*/
+ snprintf(error, (size_t) 61, "count: %d frames: %d channels: %d\n", (int) count, (int) info->frames, info->channels);
+ perror(error);
if (count == info->frames * info->channels) {
sample = (t_sample *) calloc(1, sizeof(t_sample));
View
7 file.h
@@ -13,5 +13,12 @@ typedef struct {
int *onsets;
} t_sample;
+typedef struct {
+ unsigned int frames;
+ unsigned int now;
+ float *items;
+} t_loop;
+
extern void file_set_samplerate(int s);
extern t_sample *file_get(char *samplename);
+t_loop *new_loop(float seconds);
View
28 jack.c
@@ -10,17 +10,21 @@
jack_client_t *client;
jack_port_t *output_ports[CHANNELS+1];
+jack_port_t *input_port;
int process(jack_nframes_t nframes, void *arg) {
jack_default_audio_sample_t *out[CHANNELS+1];
+ jack_default_audio_sample_t *in;
t_callback callback = (t_callback) arg;
int i;
for (i = 0; i < CHANNELS; ++i) {
out[i] = jack_port_get_buffer(output_ports[i], nframes);
}
-
- callback(nframes, out);
+
+ in = jack_port_get_buffer(input_port, nframes);
+
+ callback(nframes, in, out);
return 0;
@@ -66,6 +70,16 @@ extern jack_client_t *jack_start(t_callback callback) {
printf("engine sample rate: %" PRIu32 "\n",
jack_get_sample_rate(client));
+ strcpy(portname, "input");
+ input_port = jack_port_register(client, portname,
+ JACK_DEFAULT_AUDIO_TYPE,
+ JackPortIsInput, 0);
+
+ if (input_port == NULL) {
+ fprintf(stderr, "no JACK input ports available\n");
+ exit(1);
+ }
+
for (i = 0; i < CHANNELS; ++i) {
sprintf(portname, "output_%d", i);
output_ports[i] = jack_port_register(client, portname,
@@ -76,6 +90,7 @@ extern jack_client_t *jack_start(t_callback callback) {
exit(1);
}
}
+
output_ports[CHANNELS] = NULL;
if (jack_activate(client)) {
@@ -89,11 +104,18 @@ extern jack_client_t *jack_start(t_callback callback) {
if (ports[i] == NULL) {
break;
}
- sprintf(portname, "output_%d", i);
+ //sprintf(portname, "output_%d", i);
if (jack_connect(client, jack_port_name(output_ports[i]), ports[i])) {
fprintf(stderr, "cannot connect output ports\n");
}
}
+
+ ports = jack_get_ports(client, NULL, NULL,
+ JackPortIsPhysical|JackPortIsOutput);
+ //strcpy(portname, "input");
+ if (jack_connect(client, ports[0], jack_port_name(input_port))) {
+ fprintf(stderr, "cannot connect input port\n");
+ }
free(ports);
View
2  jack.h
@@ -2,7 +2,7 @@
#define CHANNELS 4
-typedef int (*t_callback)(int, float **);
+typedef int (*t_callback)(int, float *, float **);
extern jack_client_t *jack_start(t_callback callback);
Please sign in to comment.
Something went wrong with that request. Please try again.