Merge lp:~toni-ruottu/kunquat/triangle-dev into lp:kunquat/0.2

Proposed by Toni Ruottu
Status: Merged
Merge reported by: Toni Ruottu
Merged at revision: not available
Proposed branch: lp:~toni-ruottu/kunquat/triangle-dev
Merge into: lp:kunquat/0.2
Diff against target: None lines
To merge this branch: bzr merge lp:~toni-ruottu/kunquat/triangle-dev
Reviewer Review Type Date Requested Status
Tomi Jylhä-Ollila Pending
Review via email: mp+5882@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Toni Ruottu (toni-ruottu) wrote :

The triangle wave generator should work now. My branch uses it for the demo song. I think it is nice to hear something different, but the code for triangle wave generation is rough and not very optimized, so we could choose to continue using sine for the demo or polish the generator before a merge happens.

lp:~toni-ruottu/kunquat/triangle-dev updated
236. By Toni Ruottu

...

Revision history for this message
Sanna Fröblom (sanna-froblom) wrote :

Tried this on my EeePC, with Ubuntu Intrepid, and the song was lagging throughout the whole demo. It's unplayable unless optimised.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/Listener/Listener_ins.c'
2--- src/Listener/Listener_ins.c 2009-04-12 20:36:04 +0000
3+++ src/Listener/Listener_ins.c 2009-04-24 19:52:05 +0000
4@@ -34,6 +34,7 @@
5 #include <Ins_table.h>
6 #include <Generator_debug.h>
7 #include <Generator_sine.h>
8+#include <Generator_triangle.h>
9 #include <Generator_pcm.h>
10 #include <Instrument.h>
11 #include <Song_limits.h>
12@@ -143,6 +144,16 @@
13 gen = (Generator*)gen_sine;
14 }
15 break;
16+ case GEN_TYPE_TRIANGLE:
17+ {
18+ Generator_triangle* gen_triangle = new_Generator_triangle(Instrument_get_params(ins));
19+ if (gen_triangle == NULL)
20+ {
21+ send_memory_fail(lr, "the Generator of the new Instrument");
22+ }
23+ gen = (Generator*)gen_triangle;
24+ }
25+ break;
26 case GEN_TYPE_PCM:
27 {
28 Generator_pcm* gen_pcm = new_Generator_pcm(Instrument_get_params(ins));
29
30=== added file 'src/core/Generator_triangle.c'
31--- src/core/Generator_triangle.c 1970-01-01 00:00:00 +0000
32+++ src/core/Generator_triangle.c 2009-04-24 19:52:05 +0000
33@@ -0,0 +1,153 @@
34+
35+
36+/*
37+ * Copyright 2009 Tomi Jylhä-Ollila
38+ *
39+ * This file is part of Kunquat.
40+ *
41+ * Kunquat is free software: you can redistribute it and/or modify
42+ * it under the terms of the GNU General Public License as published by
43+ * the Free Software Foundation, either version 3 of the License, or
44+ * (at your option) any later version.
45+ *
46+ * Kunquat is distributed in the hope that it will be useful,
47+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
48+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
49+ * GNU General Public License for more details.
50+ *
51+ * You should have received a copy of the GNU General Public License
52+ * along with Kunquat. If not, see <http://www.gnu.org/licenses/>.
53+ */
54+
55+
56+#include <stdlib.h>
57+#include <assert.h>
58+#include <stdio.h>
59+#include <stdint.h>
60+#include <math.h>
61+
62+#include <Generator.h>
63+#include <Generator_triangle.h>
64+
65+#include <xmemory.h>
66+
67+
68+#define PI_2 (3.14159265358979323846 * 2)
69+
70+
71+Generator_triangle* new_Generator_triangle(Instrument_params* ins_params)
72+{
73+ assert(ins_params != NULL);
74+ Generator_triangle* triangle = xalloc(Generator_triangle);
75+ if (triangle == NULL)
76+ {
77+ return NULL;
78+ }
79+ triangle->parent.destroy = del_Generator_triangle;
80+ triangle->parent.type = GEN_TYPE_TRIANGLE;
81+ triangle->parent.init_state = Voice_state_triangle_init;
82+ triangle->parent.mix = Generator_triangle_mix;
83+ triangle->parent.ins_params = ins_params;
84+ srand (0);
85+ return triangle;
86+}
87+
88+double triangle(double x)
89+{
90+ return acos(sin(x));
91+}
92+
93+void Generator_triangle_mix(Generator* gen,
94+ Voice_state* state,
95+ uint32_t nframes,
96+ uint32_t offset,
97+ uint32_t freq)
98+{
99+ assert(gen != NULL);
100+ assert(gen->type == GEN_TYPE_TRIANGLE);
101+ assert(state != NULL);
102+// assert(nframes <= ins->buf_len); XXX: Revisit after adding instrument buffers
103+ assert(freq > 0);
104+ assert(gen->ins_params->bufs[0] != NULL);
105+ assert(gen->ins_params->bufs[1] != NULL);
106+ if (!state->active)
107+ {
108+ return;
109+ }
110+// double max_amp = 0;
111+// fprintf(stderr, "bufs are %p and %p\n", ins->bufs[0], ins->bufs[1]);
112+ for (uint32_t i = offset; i < nframes; ++i)
113+ {
114+ double val_l = 0;
115+ double val_r = 0;
116+ val_l = val_r = triangle(state->ins_fields.triangle.phase) / 6;
117+ if (!state->note_on && (state->pos_rem == 0)
118+ && !gen->ins_params->volume_off_env_enabled)
119+ {
120+ return;
121+ }
122+ if (state->pos_rem < 0.002)
123+ {
124+ val_l = val_r = val_l * (state->pos_rem * 500);
125+ state->pos_rem += 1.0 / freq;
126+ }
127+ state->ins_fields.triangle.phase += state->freq * PI_2 / freq;
128+ if (state->ins_fields.triangle.phase >= PI_2)
129+ {
130+ state->ins_fields.triangle.phase -= floor(state->ins_fields.triangle.phase / PI_2) * PI_2;
131+ ++state->pos;
132+ }
133+ if (!state->note_on)
134+ {
135+ if (gen->ins_params->volume_off_env_enabled)
136+ {
137+ double scale = Envelope_get_value(gen->ins_params->volume_off_env,
138+ state->off_ve_pos);
139+ if (!isfinite(scale))
140+ {
141+ state->active = false;
142+ return;
143+ }
144+ if (state->pedal < 0.5)
145+ {
146+ state->off_ve_pos += 1.0 / freq;
147+ }
148+ val_l *= scale;
149+ val_r *= scale;
150+ }
151+ else
152+ {
153+ if (state->noff_pos_rem < 1)
154+ {
155+ val_l = val_r = val_l * (1 - state->noff_pos_rem);
156+ }
157+ else
158+ {
159+ state->active = false;
160+ return;
161+ }
162+ state->noff_pos_rem += 2.0 / freq;
163+ }
164+ }
165+ gen->ins_params->bufs[0][i] += val_l;
166+ gen->ins_params->bufs[1][i] += val_r;
167+/* if (fabs(val_l) > max_amp)
168+ {
169+ max_amp = fabs(val_l);
170+ } */
171+ }
172+// fprintf(stderr, "max_amp is %lf\n", max_amp);
173+ return;
174+}
175+
176+
177+void del_Generator_triangle(Generator* gen)
178+{
179+ assert(gen != NULL);
180+ assert(gen->type == GEN_TYPE_TRIANGLE);
181+ Generator_triangle* triangle = (Generator_triangle*)gen;
182+ xfree(triangle);
183+ return;
184+}
185+
186+
187
188=== added file 'src/core/Generator_triangle.h'
189--- src/core/Generator_triangle.h 1970-01-01 00:00:00 +0000
190+++ src/core/Generator_triangle.h 2009-04-24 19:52:05 +0000
191@@ -0,0 +1,65 @@
192+
193+
194+/*
195+ * Copyright 2009 Tomi Jylhä-Ollila, Toni Ruottu
196+ *
197+ * This file is part of Kunquat.
198+ *
199+ * Kunquat is free software: you can redistribute it and/or modify
200+ * it under the terms of the GNU General Public License as published by
201+ * the Free Software Foundation, either version 3 of the License, or
202+ * (at your option) any later version.
203+ *
204+ * Kunquat is distributed in the hope that it will be useful,
205+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
206+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
207+ * GNU General Public License for more details.
208+ *
209+ * You should have received a copy of the GNU General Public License
210+ * along with Kunquat. If not, see <http://www.gnu.org/licenses/>.
211+ */
212+
213+
214+#ifndef K_GENERATOR_TRIANGLE_H
215+#define K_GENERATOR_TRIANGLE_H
216+
217+
218+#include <Generator.h>
219+#include <Voice_state.h>
220+
221+
222+typedef struct Generator_triangle
223+{
224+ Generator parent;
225+} Generator_triangle;
226+
227+
228+/**
229+ * Creates a new Triangle Generator.
230+ *
231+ * \param ins_params The Instrument parameters -- must not be \c NULL.
232+ *
233+ * \return The new Triangle Generator if successful, or \c NULL if memory
234+ * allocation failed.
235+ */
236+Generator_triangle* new_Generator_triangle(Instrument_params* ins_params);
237+
238+
239+void Generator_triangle_mix(Generator* gen,
240+ Voice_state* state,
241+ uint32_t nframes,
242+ uint32_t offset,
243+ uint32_t freq);
244+
245+
246+/**
247+ * Destroys an existing Triangle Generator.
248+ *
249+ * \param gen The Triangle Generator -- must not be \c NULL.
250+ */
251+void del_Generator_triangle(Generator* gen);
252+
253+
254+#endif // K_GENERATOR_TRIANGLE_H
255+
256+
257
258=== modified file 'src/core/Generator_type.h'
259--- src/core/Generator_type.h 2009-04-12 20:36:04 +0000
260+++ src/core/Generator_type.h 2009-04-24 19:52:05 +0000
261@@ -35,6 +35,8 @@
262 GEN_TYPE_DEBUG,
263 /// A simple sine wave instrument for testing by ear.
264 GEN_TYPE_SINE,
265+ /// A simple triangle wave instrument.
266+ GEN_TYPE_TRIANGLE,
267 /// A sample-based type common in tracker programs.
268 GEN_TYPE_PCM,
269 /// A type for reading audio data from disk -- used for large audio files.
270
271=== modified file 'src/core/SConscript'
272--- src/core/SConscript 2009-04-12 20:36:04 +0000
273+++ src/core/SConscript 2009-04-24 19:52:05 +0000
274@@ -60,6 +60,7 @@
275 'Playdata.c',
276 'Player.c',
277 'Playlist.c',
278+ 'Generator_triangle.c',
279 ]
280
281 if env['with_jack']:
282
283=== modified file 'src/core/Voice_state.c'
284--- src/core/Voice_state.c 2009-04-12 23:05:15 +0000
285+++ src/core/Voice_state.c 2009-04-24 19:52:05 +0000
286@@ -67,3 +67,11 @@
287 }
288
289
290+void Voice_state_triangle_init(Voice_state* state)
291+{
292+ assert(state != NULL);
293+ state->ins_fields.triangle.phase = 0;
294+ return;
295+}
296+
297+
298
299=== modified file 'src/core/Voice_state.h'
300--- src/core/Voice_state.h 2009-03-11 01:10:24 +0000
301+++ src/core/Voice_state.h 2009-04-24 19:52:05 +0000
302@@ -31,6 +31,12 @@
303 #include <pitch_t.h>
304
305
306+typedef struct Voice_state_triangle
307+{
308+ double phase;
309+} Voice_state_triangle;
310+
311+
312 typedef struct Voice_state_sine
313 {
314 double phase;
315@@ -67,6 +73,7 @@
316 union
317 {
318 Voice_state_sine sine;
319+ Voice_state_triangle triangle;
320 // Voice_state_pcm pcm;
321 } ins_fields;
322 } Voice_state;
323@@ -101,6 +108,14 @@
324 void Voice_state_sine_init(Voice_state* state);
325
326
327+/**
328+ * Initialises the Triangle Instrument parameters.
329+ *
330+ * \param triangle The Triangle parameters -- must not be \c NULL.
331+ */
332+void Voice_state_triangle_init(Voice_state* state);
333+
334+
335 #endif // K_VOICE_STATE_H
336
337
338
339=== modified file 'src/demo/demo_song.c'
340--- src/demo/demo_song.c 2009-04-12 20:36:04 +0000
341+++ src/demo/demo_song.c 2009-04-24 19:52:05 +0000
342@@ -24,7 +24,7 @@
343
344 #include "demo_song.h"
345
346-#include <Generator_sine.h>
347+#include <Generator_triangle.h>
348
349
350 typedef struct Ndesc
351@@ -139,14 +139,14 @@
352 {
353 goto cleanup;
354 }
355- Generator_sine* sine_gen = new_Generator_sine(Instrument_get_params(ins));
356- if (sine_gen == NULL)
357+ Generator_triangle* triangle_gen = new_Generator_triangle(Instrument_get_params(ins));
358+ if (triangle_gen == NULL)
359 {
360 del_Instrument(ins);
361 goto cleanup;
362 }
363- Instrument_set_gen(ins, 0, (Generator*)sine_gen);
364- Instrument_set_name(ins, L"sine");
365+ Instrument_set_gen(ins, 0, (Generator*)triangle_gen);
366+ Instrument_set_name(ins, L"triangle");
367 Instrument_set_note_table(ins, Song_get_active_notes(song));
368 Ins_table* insts = Song_get_insts(song);
369 if (!Ins_table_set(insts, 1, ins))
370
371=== modified file 'src/ui_pygtk/Instruments.py'
372--- src/ui_pygtk/Instruments.py 2009-01-07 00:07:37 +0000
373+++ src/ui_pygtk/Instruments.py 2009-04-24 19:52:05 +0000
374@@ -479,6 +479,7 @@
375 self.types = gtk.combo_box_new_text()
376 self.types.append_text('None')
377 self.types.append_text('Sine')
378+ self.types.append_text('Triangle')
379 self.types.append_text('PCM')
380 self.types.set_active(0)
381 self.htypes = self.types.connect('changed', self.change_type)

Subscribers

People subscribed via source and target branches

to all changes: