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
29 #include "generator.h"
34 #define GENERATOR_CLASS_NAME "resample"
35 #define GENERATOR_CLASS_PATH "Timebase/Resample"
47 #define FREQ_C0 16.351598
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
));
62 PRIVATE
void destroy_instance(Generator
*g
) {
66 PRIVATE
void unpickle_instance(Generator
*g
, ObjectStoreItem
*item
, ObjectStore
*db
) {
67 Data
*data
= safe_malloc(sizeof(Data
));
70 data
->factor
= objectstore_item_get_double(item
, "resample_factor", 1);
73 PRIVATE
void pickle_instance(Generator
*g
, ObjectStoreItem
*item
, ObjectStore
*db
) {
75 objectstore_item_set_double(item
, "resample_factor", data
->factor
);
78 PRIVATE SAMPLETIME
output_range(Generator
*g
, OutputSignalDescriptor
*sig
) {
81 if (data
->factor
== 0)
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
) {
90 SAMPLE tmpbuf
[MAXIMUM_REALTIME_STEP
*5];
94 if (!gen_read_randomaccess_input(g
, SIG_INPUT
, 0,
95 offset
*data
->factor
, tmpbuf
, buflen
*data
->factor
+ 1))
98 for (i
= 0, o
= 0; i
< buflen
; i
++, o
+= data
->factor
) {
100 gdouble fract
= o
- oi
;
101 buf
[i
] = ( tmpbuf
[oi
]*(1-fract
) + tmpbuf
[oi
+1]*fract
) / 2;
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
},
120 PRIVATE OutputSignalDescriptor output_sigs
[] = {
121 { "Output", SIG_FLAG_RANDOMACCESS
, { NULL
, { output_range
, output_generator
} } },
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
,
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) {