1 /*
2 TiMidity++ -- MIDI to WAVE converter and player
3 Copyright (C) 1999-2004 Masanao Izumo <iz@onicos.co.jp>
4 Copyright (C) 1995 Tuukka Toivonen <tt@cgs.fi>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20 effect.c - To apply sound effects.
21 Mainly written by Masanao Izumo <iz@onicos.co.jp>
22
23 Interfaces:
24 void init_effect(void);
25 do_effect(int32_t* buf, int32_t count);
26 */
27
28 #include <string.h>
29 #include <stdlib.h>
30
31 #include "effect.h"
32 #include "instrum.h"
33 #include "playmidi.h"
34 #include "reverb.h"
35
36
37 namespace TimidityPlus
38 {
39
40
41
42 #define SIDE_CONTI_SEC 10
43 #define CHANGE_SEC 2.0
44
init_effect()45 void Effect::init_effect()
46 {
47 effect_left_right_delay(NULL, 0);
48 reverb->init_for_effect();
49 }
50
51 /*
52 * Left & Right Delay Effect
53 */
effect_left_right_delay(int32_t * buff,int32_t count)54 void Effect::effect_left_right_delay(int32_t *buff, int32_t count)
55 {
56 int32_t save[AUDIO_BUFFER_SIZE * 2];
57 int32_t pi, i, j, k, v, backoff;
58 int b;
59 int32_t *p;
60
61 if (buff == NULL)
62 {
63 memset(prev, 0, sizeof(prev));
64 return;
65 }
66 if (effect_lr_mode == 0 || effect_lr_mode == 1 || effect_lr_mode == 2)
67 b = effect_lr_mode;
68 else
69 return;
70 count *= 2;
71 backoff = 2 * (int)(playback_rate * effect_lr_delay_msec / 1000.0);
72 if (backoff == 0)
73 return;
74 if (backoff > count)
75 backoff = count;
76 if (count < AUDIO_BUFFER_SIZE * 2)
77 {
78 memset(buff + count, 0, 4 * (AUDIO_BUFFER_SIZE * 2 - count));
79 count = AUDIO_BUFFER_SIZE * 2;
80 }
81 memcpy(save, buff, 4 * count);
82 pi = count - backoff;
83 if (b == 2)
84 {
85 if (turn_counter == 0)
86 {
87 turn_counter = SIDE_CONTI_SEC * playback_rate;
88 /* status: 0 -> 2 -> 3 -> 1 -> 4 -> 5 -> 0 -> ...
89 * status left right
90 * 0 - + (right)
91 * 1 + - (left)
92 * 2 -> + + (right -> center)
93 * 3 + -> - (center -> left)
94 * 4 -> - - (left -> center)
95 * 5 - -> + (center -> right)
96 */
97 status = 0;
98 tc = 0;
99 }
100 p = prev;
101 for (i = 0; i < count; i += 2, pi += 2)
102 {
103 if (i < backoff)
104 p = prev;
105 else if (p == prev)
106 {
107 pi = 0;
108 p = save;
109 }
110 if (status < 2)
111 buff[i + status] = p[pi + status];
112 else if (status < 4)
113 {
114 j = (status & 1);
115 v = (int32_t)(rate0 * buff[i + j] + rate1 * p[pi + j]);
116 buff[i + j] = v;
117 rate0 += dr, rate1 -= dr;
118 }
119 else
120 {
121 j = (status & 1);
122 k = !j;
123 v = (int32_t)(rate0 * buff[i + j] + rate1 * p[pi + j]);
124 buff[i + j] = v;
125 buff[i + k] = p[pi + k];
126 rate0 += dr, rate1 -= dr;
127 }
128 tc++;
129 if (tc == turn_counter)
130 {
131 tc = 0;
132 switch (status)
133 {
134 case 0:
135 status = 2;
136 turn_counter = (CHANGE_SEC / 2.0) * playback_rate;
137 rate0 = 0.0;
138 rate1 = 1.0;
139 dr = 1.0 / turn_counter;
140 break;
141 case 2:
142 status = 3;
143 rate0 = 1.0;
144 rate1 = 0.0;
145 dr = -1.0 / turn_counter;
146 break;
147 case 3:
148 status = 1;
149 turn_counter = SIDE_CONTI_SEC * playback_rate;
150 break;
151 case 1:
152 status = 4;
153 turn_counter = (CHANGE_SEC / 2.0) * playback_rate;
154 rate0 = 1.0;
155 rate1 = 0.0;
156 dr = -1.0 / turn_counter;
157 break;
158 case 4:
159 status = 5;
160 turn_counter = (CHANGE_SEC / 2.0) * playback_rate;
161 rate0 = 0.0;
162 rate1 = 1.0;
163 dr = 1.0 / turn_counter;
164 break;
165 case 5:
166 status = 0;
167 turn_counter = SIDE_CONTI_SEC * playback_rate;
168 break;
169 }
170 }
171 }
172 }
173 else
174 {
175 for (i = 0; i < backoff; i += 2, pi += 2)
176 buff[b + i] = prev[b + pi];
177 for (pi = 0; i < count; i += 2, pi += 2)
178 buff[b + i] = save[b + pi];
179 }
180 memcpy(prev + count - backoff, save + count - backoff, 4 * backoff);
181 }
182
do_effect(int32_t * buf,int32_t count)183 void Effect::do_effect(int32_t *buf, int32_t count)
184 {
185 int32_t nsamples = count * 2;
186 int reverb_level = (timidity_reverb < 0)
187 ? -timidity_reverb & 0x7f : DEFAULT_REVERB_SEND_LEVEL;
188
189 /* for static reverb / chorus level */
190 if (timidity_reverb == 2 || timidity_reverb == 4
191 || (timidity_reverb < 0 && !(timidity_reverb & 0x80))
192 || timidity_chorus < 0)
193 {
194 reverb->set_dry_signal(buf, nsamples);
195 /* chorus sounds horrible
196 * if applied globally on top of channel chorus
197 */
198 if (timidity_reverb == 2 || timidity_reverb == 4
199 || (timidity_reverb < 0 && !(timidity_reverb & 0x80)))
200 reverb->set_ch_reverb(buf, nsamples, reverb_level);
201 reverb->mix_dry_signal(buf, nsamples);
202 /* chorus sounds horrible
203 * if applied globally on top of channel chorus
204 */
205 if (timidity_reverb == 2 || timidity_reverb == 4
206 || (timidity_reverb < 0 && !(timidity_reverb & 0x80)))
207 reverb->do_ch_reverb(buf, nsamples);
208 }
209 /* L/R Delay */
210 effect_left_right_delay(buf, count);
211 }
212
my_mod(int32_t x,int32_t n)213 int32_t Effect::my_mod(int32_t x, int32_t n)
214 {
215 if (x >= n)
216 x -= n;
217 return x;
218 }
219
220 }