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
=== modified file 'src/Listener/Listener_ins.c'
--- src/Listener/Listener_ins.c 2009-04-12 20:36:04 +0000
+++ src/Listener/Listener_ins.c 2009-04-24 19:52:05 +0000
@@ -34,6 +34,7 @@
34#include <Ins_table.h>34#include <Ins_table.h>
35#include <Generator_debug.h>35#include <Generator_debug.h>
36#include <Generator_sine.h>36#include <Generator_sine.h>
37#include <Generator_triangle.h>
37#include <Generator_pcm.h>38#include <Generator_pcm.h>
38#include <Instrument.h>39#include <Instrument.h>
39#include <Song_limits.h>40#include <Song_limits.h>
@@ -143,6 +144,16 @@
143 gen = (Generator*)gen_sine;144 gen = (Generator*)gen_sine;
144 }145 }
145 break;146 break;
147 case GEN_TYPE_TRIANGLE:
148 {
149 Generator_triangle* gen_triangle = new_Generator_triangle(Instrument_get_params(ins));
150 if (gen_triangle == NULL)
151 {
152 send_memory_fail(lr, "the Generator of the new Instrument");
153 }
154 gen = (Generator*)gen_triangle;
155 }
156 break;
146 case GEN_TYPE_PCM:157 case GEN_TYPE_PCM:
147 {158 {
148 Generator_pcm* gen_pcm = new_Generator_pcm(Instrument_get_params(ins));159 Generator_pcm* gen_pcm = new_Generator_pcm(Instrument_get_params(ins));
149160
=== added file 'src/core/Generator_triangle.c'
--- src/core/Generator_triangle.c 1970-01-01 00:00:00 +0000
+++ src/core/Generator_triangle.c 2009-04-24 19:52:05 +0000
@@ -0,0 +1,153 @@
1
2
3/*
4 * Copyright 2009 Tomi Jylhä-Ollila
5 *
6 * This file is part of Kunquat.
7 *
8 * Kunquat is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * Kunquat is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with Kunquat. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22
23#include <stdlib.h>
24#include <assert.h>
25#include <stdio.h>
26#include <stdint.h>
27#include <math.h>
28
29#include <Generator.h>
30#include <Generator_triangle.h>
31
32#include <xmemory.h>
33
34
35#define PI_2 (3.14159265358979323846 * 2)
36
37
38Generator_triangle* new_Generator_triangle(Instrument_params* ins_params)
39{
40 assert(ins_params != NULL);
41 Generator_triangle* triangle = xalloc(Generator_triangle);
42 if (triangle == NULL)
43 {
44 return NULL;
45 }
46 triangle->parent.destroy = del_Generator_triangle;
47 triangle->parent.type = GEN_TYPE_TRIANGLE;
48 triangle->parent.init_state = Voice_state_triangle_init;
49 triangle->parent.mix = Generator_triangle_mix;
50 triangle->parent.ins_params = ins_params;
51 srand (0);
52 return triangle;
53}
54
55double triangle(double x)
56{
57 return acos(sin(x));
58}
59
60void Generator_triangle_mix(Generator* gen,
61 Voice_state* state,
62 uint32_t nframes,
63 uint32_t offset,
64 uint32_t freq)
65{
66 assert(gen != NULL);
67 assert(gen->type == GEN_TYPE_TRIANGLE);
68 assert(state != NULL);
69// assert(nframes <= ins->buf_len); XXX: Revisit after adding instrument buffers
70 assert(freq > 0);
71 assert(gen->ins_params->bufs[0] != NULL);
72 assert(gen->ins_params->bufs[1] != NULL);
73 if (!state->active)
74 {
75 return;
76 }
77// double max_amp = 0;
78// fprintf(stderr, "bufs are %p and %p\n", ins->bufs[0], ins->bufs[1]);
79 for (uint32_t i = offset; i < nframes; ++i)
80 {
81 double val_l = 0;
82 double val_r = 0;
83 val_l = val_r = triangle(state->ins_fields.triangle.phase) / 6;
84 if (!state->note_on && (state->pos_rem == 0)
85 && !gen->ins_params->volume_off_env_enabled)
86 {
87 return;
88 }
89 if (state->pos_rem < 0.002)
90 {
91 val_l = val_r = val_l * (state->pos_rem * 500);
92 state->pos_rem += 1.0 / freq;
93 }
94 state->ins_fields.triangle.phase += state->freq * PI_2 / freq;
95 if (state->ins_fields.triangle.phase >= PI_2)
96 {
97 state->ins_fields.triangle.phase -= floor(state->ins_fields.triangle.phase / PI_2) * PI_2;
98 ++state->pos;
99 }
100 if (!state->note_on)
101 {
102 if (gen->ins_params->volume_off_env_enabled)
103 {
104 double scale = Envelope_get_value(gen->ins_params->volume_off_env,
105 state->off_ve_pos);
106 if (!isfinite(scale))
107 {
108 state->active = false;
109 return;
110 }
111 if (state->pedal < 0.5)
112 {
113 state->off_ve_pos += 1.0 / freq;
114 }
115 val_l *= scale;
116 val_r *= scale;
117 }
118 else
119 {
120 if (state->noff_pos_rem < 1)
121 {
122 val_l = val_r = val_l * (1 - state->noff_pos_rem);
123 }
124 else
125 {
126 state->active = false;
127 return;
128 }
129 state->noff_pos_rem += 2.0 / freq;
130 }
131 }
132 gen->ins_params->bufs[0][i] += val_l;
133 gen->ins_params->bufs[1][i] += val_r;
134/* if (fabs(val_l) > max_amp)
135 {
136 max_amp = fabs(val_l);
137 } */
138 }
139// fprintf(stderr, "max_amp is %lf\n", max_amp);
140 return;
141}
142
143
144void del_Generator_triangle(Generator* gen)
145{
146 assert(gen != NULL);
147 assert(gen->type == GEN_TYPE_TRIANGLE);
148 Generator_triangle* triangle = (Generator_triangle*)gen;
149 xfree(triangle);
150 return;
151}
152
153
0154
=== added file 'src/core/Generator_triangle.h'
--- src/core/Generator_triangle.h 1970-01-01 00:00:00 +0000
+++ src/core/Generator_triangle.h 2009-04-24 19:52:05 +0000
@@ -0,0 +1,65 @@
1
2
3/*
4 * Copyright 2009 Tomi Jylhä-Ollila, Toni Ruottu
5 *
6 * This file is part of Kunquat.
7 *
8 * Kunquat is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * Kunquat is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with Kunquat. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22
23#ifndef K_GENERATOR_TRIANGLE_H
24#define K_GENERATOR_TRIANGLE_H
25
26
27#include <Generator.h>
28#include <Voice_state.h>
29
30
31typedef struct Generator_triangle
32{
33 Generator parent;
34} Generator_triangle;
35
36
37/**
38 * Creates a new Triangle Generator.
39 *
40 * \param ins_params The Instrument parameters -- must not be \c NULL.
41 *
42 * \return The new Triangle Generator if successful, or \c NULL if memory
43 * allocation failed.
44 */
45Generator_triangle* new_Generator_triangle(Instrument_params* ins_params);
46
47
48void Generator_triangle_mix(Generator* gen,
49 Voice_state* state,
50 uint32_t nframes,
51 uint32_t offset,
52 uint32_t freq);
53
54
55/**
56 * Destroys an existing Triangle Generator.
57 *
58 * \param gen The Triangle Generator -- must not be \c NULL.
59 */
60void del_Generator_triangle(Generator* gen);
61
62
63#endif // K_GENERATOR_TRIANGLE_H
64
65
066
=== modified file 'src/core/Generator_type.h'
--- src/core/Generator_type.h 2009-04-12 20:36:04 +0000
+++ src/core/Generator_type.h 2009-04-24 19:52:05 +0000
@@ -35,6 +35,8 @@
35 GEN_TYPE_DEBUG,35 GEN_TYPE_DEBUG,
36 /// A simple sine wave instrument for testing by ear.36 /// A simple sine wave instrument for testing by ear.
37 GEN_TYPE_SINE,37 GEN_TYPE_SINE,
38 /// A simple triangle wave instrument.
39 GEN_TYPE_TRIANGLE,
38 /// A sample-based type common in tracker programs.40 /// A sample-based type common in tracker programs.
39 GEN_TYPE_PCM,41 GEN_TYPE_PCM,
40 /// A type for reading audio data from disk -- used for large audio files.42 /// A type for reading audio data from disk -- used for large audio files.
4143
=== modified file 'src/core/SConscript'
--- src/core/SConscript 2009-04-12 20:36:04 +0000
+++ src/core/SConscript 2009-04-24 19:52:05 +0000
@@ -60,6 +60,7 @@
60 'Playdata.c',60 'Playdata.c',
61 'Player.c',61 'Player.c',
62 'Playlist.c',62 'Playlist.c',
63 'Generator_triangle.c',
63]64]
6465
65if env['with_jack']:66if env['with_jack']:
6667
=== modified file 'src/core/Voice_state.c'
--- src/core/Voice_state.c 2009-04-12 23:05:15 +0000
+++ src/core/Voice_state.c 2009-04-24 19:52:05 +0000
@@ -67,3 +67,11 @@
67}67}
6868
6969
70void Voice_state_triangle_init(Voice_state* state)
71{
72 assert(state != NULL);
73 state->ins_fields.triangle.phase = 0;
74 return;
75}
76
77
7078
=== modified file 'src/core/Voice_state.h'
--- src/core/Voice_state.h 2009-03-11 01:10:24 +0000
+++ src/core/Voice_state.h 2009-04-24 19:52:05 +0000
@@ -31,6 +31,12 @@
31#include <pitch_t.h>31#include <pitch_t.h>
3232
3333
34typedef struct Voice_state_triangle
35{
36 double phase;
37} Voice_state_triangle;
38
39
34typedef struct Voice_state_sine40typedef struct Voice_state_sine
35{41{
36 double phase;42 double phase;
@@ -67,6 +73,7 @@
67 union73 union
68 {74 {
69 Voice_state_sine sine;75 Voice_state_sine sine;
76 Voice_state_triangle triangle;
70// Voice_state_pcm pcm;77// Voice_state_pcm pcm;
71 } ins_fields;78 } ins_fields;
72} Voice_state;79} Voice_state;
@@ -101,6 +108,14 @@
101void Voice_state_sine_init(Voice_state* state);108void Voice_state_sine_init(Voice_state* state);
102109
103110
111/**
112 * Initialises the Triangle Instrument parameters.
113 *
114 * \param triangle The Triangle parameters -- must not be \c NULL.
115 */
116void Voice_state_triangle_init(Voice_state* state);
117
118
104#endif // K_VOICE_STATE_H119#endif // K_VOICE_STATE_H
105120
106121
107122
=== modified file 'src/demo/demo_song.c'
--- src/demo/demo_song.c 2009-04-12 20:36:04 +0000
+++ src/demo/demo_song.c 2009-04-24 19:52:05 +0000
@@ -24,7 +24,7 @@
2424
25#include "demo_song.h"25#include "demo_song.h"
2626
27#include <Generator_sine.h>27#include <Generator_triangle.h>
2828
2929
30typedef struct Ndesc30typedef struct Ndesc
@@ -139,14 +139,14 @@
139 {139 {
140 goto cleanup;140 goto cleanup;
141 }141 }
142 Generator_sine* sine_gen = new_Generator_sine(Instrument_get_params(ins));142 Generator_triangle* triangle_gen = new_Generator_triangle(Instrument_get_params(ins));
143 if (sine_gen == NULL)143 if (triangle_gen == NULL)
144 {144 {
145 del_Instrument(ins);145 del_Instrument(ins);
146 goto cleanup;146 goto cleanup;
147 }147 }
148 Instrument_set_gen(ins, 0, (Generator*)sine_gen);148 Instrument_set_gen(ins, 0, (Generator*)triangle_gen);
149 Instrument_set_name(ins, L"sine");149 Instrument_set_name(ins, L"triangle");
150 Instrument_set_note_table(ins, Song_get_active_notes(song));150 Instrument_set_note_table(ins, Song_get_active_notes(song));
151 Ins_table* insts = Song_get_insts(song);151 Ins_table* insts = Song_get_insts(song);
152 if (!Ins_table_set(insts, 1, ins))152 if (!Ins_table_set(insts, 1, ins))
153153
=== modified file 'src/ui_pygtk/Instruments.py'
--- src/ui_pygtk/Instruments.py 2009-01-07 00:07:37 +0000
+++ src/ui_pygtk/Instruments.py 2009-04-24 19:52:05 +0000
@@ -479,6 +479,7 @@
479 self.types = gtk.combo_box_new_text()479 self.types = gtk.combo_box_new_text()
480 self.types.append_text('None')480 self.types.append_text('None')
481 self.types.append_text('Sine')481 self.types.append_text('Sine')
482 self.types.append_text('Triangle')
482 self.types.append_text('PCM')483 self.types.append_text('PCM')
483 self.types.set_active(0)484 self.types.set_active(0)
484 self.htypes = self.types.connect('changed', self.change_type)485 self.htypes = self.types.connect('changed', self.change_type)

Subscribers

People subscribed via source and target branches

to all changes: