Permalink
Browse files

audio input

  • Loading branch information...
1 parent 030581c commit 5898624f8954a501f1ccb7c8aee026f1c9db335f @yaxu yaxu committed Jul 26, 2012
Showing with 167 additions and 71 deletions.
  1. +104 −58 audio.c
  2. +11 −3 audio.h
  3. +1 −0 dirt.c
  4. +18 −6 file.c
  5. +7 −0 file.h
  6. +25 −3 jack.c
  7. +1 −1 jack.h
View
162 audio.c
@@ -16,17 +16,19 @@ pthread_mutex_t queue_waiting_lock;
t_sound *waiting = NULL;
t_sound *playing = NULL;
+t_loop *loop = NULL;
+
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);
+ loop = new_loop(8);
}
int queue_size(t_sound *queue) {
@@ -167,58 +169,81 @@ 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);
-
+ int is_loop = 0;
+ 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;
+ if (strcmp(samplename, "loop") == 0) {
+ is_loop = 1;
+ }
+ else {
+ sample = file_get(samplename);
+ if (sample == NULL) {
+ return(0);
+ }
+ }
+
+ 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);
+
+ 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 {
+ new->sample = sample;
+ new->frames = sample->info->frames;
+ new->items = sample->items;
+ new->channels = sample->info->channels;
+ }
+ new->is_loop = is_loop;
- 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 +297,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;
+
+ 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 {
+ value = p->items[(channels * ((int) p->position)) + channel];
+ }
+
int pos = ((int) p->position) + 1;
- if (pos < p->frames) {
- float next =
- p->sample->items[(channels * pos)
- + channel
- ];
+ if ((!p->is_loop) && pos < p->frames) {
+ float next;
+ if (p->is_loop) {
+ // only one channel, but relative to 'now'
+ unsigned int i = (p->loop_start + pos) % p->loop->frames;
+ value = p->items[i];
+ }
+ else {
+ next =
+ p->items[(channels * pos)
+ + channel
+ ];
+ }
float tween_amount = (p->position - (int) p->position);
@@ -345,7 +387,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 +398,17 @@ 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) {
+ loop->items[loop->now++] = input[i];
+ if (loop->now >= loop->frames) {
+ loop->now = 0;
+ }
+
dequeue(now + frames);
- playback(buffers, i, now + i);
+ playback(outputs, i, now + i);
}
return(0);
}
View
14 audio.h
@@ -5,12 +5,20 @@
#define MAXDELAYS 16
#define MAXDELAY 44100
-#define ROUNDOFF 16
+#define ROUNDOFF 8
+
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 +31,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
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);
Oops, something went wrong.

0 comments on commit 5898624

Please sign in to comment.