missing commit in generator.h
[galan.git] / plugins / libresample.c
blob723ff7db120d2f3ed554e5e398fc1d7081ecca49
1 /* gAlan - Graphical Audio Language
2 * Copyright (C) 1999 Tony Garnock-Jones
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include <stdlib.h>
20 #include <string.h>
21 #include <stdio.h>
22 #include <stddef.h>
24 #include <gdk/gdk.h>
25 #include <gtk/gtk.h>
26 #include <gmodule.h>
28 #include "global.h"
29 #include "generator.h"
30 #include "comp.h"
31 #include "control.h"
32 #include "gencomp.h"
34 #define GENERATOR_CLASS_NAME "resample"
35 #define GENERATOR_CLASS_PATH "Timebase/Resample"
37 #define SIG_INPUT 0
38 #define SIG_OUTPUT 0
40 #define EVT_FACTOR 0
41 #define EVT_NOTE 1
43 typedef struct Data {
44 gdouble factor;
45 } Data;
47 #define FREQ_C0 16.351598
48 #define FREQ_A4 440
49 #define NOTE_C4 48
50 #define NOTE_A4 57
51 #define NOTE_TO_FACTOR(n, centre) (pow(2, ((n) - (centre)) / 12.0))
53 PRIVATE int init_instance(Generator *g) {
54 Data *data = safe_malloc(sizeof(Data));
55 g->data = data;
57 data->factor = 1;
59 return 1;
62 PRIVATE void destroy_instance(Generator *g) {
63 free(g->data);
66 PRIVATE void unpickle_instance(Generator *g, ObjectStoreItem *item, ObjectStore *db) {
67 Data *data = safe_malloc(sizeof(Data));
68 g->data = data;
70 data->factor = objectstore_item_get_double(item, "resample_factor", 1);
73 PRIVATE void pickle_instance(Generator *g, ObjectStoreItem *item, ObjectStore *db) {
74 Data *data = g->data;
75 objectstore_item_set_double(item, "resample_factor", data->factor);
78 PRIVATE SAMPLETIME output_range(Generator *g, OutputSignalDescriptor *sig) {
79 Data *data = g->data;
81 if (data->factor == 0)
82 return 0; /* GIGO */
84 return gen_get_randomaccess_input_range(g, SIG_INPUT, 0) / data->factor;
87 PRIVATE gboolean output_generator(Generator *g, OutputSignalDescriptor *sig,
88 SAMPLETIME offset, SAMPLE *buf, int buflen) {
89 Data *data = g->data;
90 SAMPLE tmpbuf[MAXIMUM_REALTIME_STEP*5];
91 int i;
92 gdouble o;
94 if (!gen_read_randomaccess_input(g, SIG_INPUT, 0,
95 offset*data->factor, tmpbuf, buflen*data->factor + 1))
96 return FALSE;
98 for (i = 0, o = 0; i < buflen; i++, o += data->factor) {
99 int oi = floor(o);
100 gdouble fract = o - oi;
101 buf[i] = ( tmpbuf[oi]*(1-fract) + tmpbuf[oi+1]*fract ) / 2;
104 return TRUE;
107 PRIVATE void evt_factor_handler(Generator *g, AEvent *event) {
108 ((Data *) g->data)->factor = MAX(MIN(event->d.number, 4), 0);
111 PRIVATE void evt_note_handler(Generator *g, AEvent *event) {
112 ((Data *) g->data)->factor = MAX(MIN(NOTE_TO_FACTOR(event->d.number, NOTE_C4), 4), 0);
115 PRIVATE InputSignalDescriptor input_sigs[] = {
116 { "Input", SIG_FLAG_RANDOMACCESS },
117 { NULL, }
120 PRIVATE OutputSignalDescriptor output_sigs[] = {
121 { "Output", SIG_FLAG_RANDOMACCESS, { NULL, { output_range, output_generator } } },
122 { NULL, }
125 PRIVATE ControlDescriptor controls[] = {
126 /* { kind, name, min,max,step,page, size,editable, is_dst,queue_number,
127 init,destroy,refresh,refresh_data }, */
128 { CONTROL_KIND_KNOB, "factor", 0.5,4,0.01,0.01, 0,TRUE, TRUE,EVT_FACTOR,
129 NULL,NULL, control_double_updater, (gpointer) offsetof(Data, factor) },
130 { CONTROL_KIND_KNOB, "note", 0,127,1,1, 0,TRUE, TRUE,EVT_NOTE,
131 NULL,NULL, NULL },
132 { CONTROL_KIND_NONE, }
135 PRIVATE void setup_class(void) {
136 GeneratorClass *k = gen_new_generatorclass(GENERATOR_CLASS_NAME, FALSE, 2, 0,
137 input_sigs, output_sigs, controls,
138 init_instance, destroy_instance,
139 unpickle_instance, pickle_instance);
141 gen_configure_event_input(k, EVT_FACTOR, "Factor", evt_factor_handler);
142 gen_configure_event_input(k, EVT_NOTE, "Note", evt_note_handler);
144 gencomp_register_generatorclass(k, FALSE, GENERATOR_CLASS_PATH, NULL, NULL);
147 PUBLIC void init_plugin(void) {
148 setup_class();