1 /*
2 * sample.c -- Midi Wavetable Processing library
3 *
4 * Copyright (C) WildMIDI Developers 2001-2016
5 *
6 * This file is part of WildMIDI.
7 *
8 * WildMIDI is free software: you can redistribute and/or modify the player
9 * under the terms of the GNU General Public License and you can redistribute
10 * and/or modify the library under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation, either version 3 of
12 * the licenses, or(at your option) any later version.
13 *
14 * WildMIDI is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License and
17 * the GNU Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License and the
20 * GNU Lesser General Public License along with WildMIDI. If not, see
21 * <http://www.gnu.org/licenses/>.
22 */
23
24 #include "config.h"
25
26 #include <stdio.h>
27 #include <stdint.h>
28
29 #include "lock.h"
30 #include "common.h"
31 #include "patches.h"
32 #include "gus_pat.h"
33 #include "wildmidi_lib.h"
34 #include "internal_midi.h"
35 #include "sample.h"
36
37 /*
38 FIXME: Need to decide if this stuff needs to be broken up for different formats.
39 */
40
_WM_get_decay_samples(struct _mdi * mdi,uint8_t channel,uint8_t note)41 uint32_t _WM_get_decay_samples(struct _mdi * mdi, uint8_t channel, uint8_t note) {
42 struct _patch *patch = NULL;
43 struct _sample *sample = NULL;
44 uint32_t freq = 0;
45 uint32_t decay_samples = 0;
46
47 if (mdi->channel[channel].isdrum) {
48 patch = _WM_get_patch_data(mdi,
49 ((mdi->channel[channel].bank << 8)
50 | note | 0x80));
51 } else {
52 patch = mdi->channel[channel].patch;
53 }
54
55 if (patch == NULL) return (0);
56
57 /* first get the freq we need so we can check the right sample */
58 if (patch->patchid & 0x80) {
59 /* is a drum patch */
60 if (patch->note) {
61 freq = _WM_freq_table[(patch->note % 12) * 100]
62 >> (10 - (patch->note / 12));
63 } else {
64 freq = _WM_freq_table[(note % 12) * 100] >> (10 - (note / 12));
65 }
66 } else {
67 freq = _WM_freq_table[(note % 12) * 100] >> (10 - (note / 12));
68 }
69
70 /* get the sample */
71 sample = _WM_get_sample_data(patch, (freq / 100));
72 if (sample == NULL) return (0);
73
74 decay_samples = sample->note_off_decay;
75
76 return (decay_samples);
77 }
78
79
_WM_get_sample_data(struct _patch * sample_patch,uint32_t freq)80 struct _sample *_WM_get_sample_data(struct _patch *sample_patch, uint32_t freq) {
81 struct _sample *last_sample = NULL;
82 struct _sample *return_sample = NULL;
83
84 _WM_Lock(&_WM_patch_lock);
85 if (sample_patch == NULL) {
86 _WM_Unlock(&_WM_patch_lock);
87 return (NULL);
88 }
89 if (sample_patch->first_sample == NULL) {
90 _WM_Unlock(&_WM_patch_lock);
91 return (NULL);
92 }
93 if (freq == 0) {
94 _WM_Unlock(&_WM_patch_lock);
95 return (sample_patch->first_sample);
96 }
97
98 return_sample = sample_patch->first_sample;
99 last_sample = sample_patch->first_sample;
100 while (last_sample) {
101 if (freq > last_sample->freq_low) {
102 if (freq < last_sample->freq_high) {
103 _WM_Unlock(&_WM_patch_lock);
104 return (last_sample);
105 } else {
106 return_sample = last_sample;
107 }
108 }
109 last_sample = last_sample->next;
110 }
111 _WM_Unlock(&_WM_patch_lock);
112 return (return_sample);
113 }
114
115 /* sample loading */
116
117 int
_WM_load_sample(struct _patch * sample_patch)118 _WM_load_sample(struct _patch *sample_patch) {
119 struct _sample *guspat = NULL;
120 struct _sample *tmp_sample = NULL;
121 uint32_t i = 0;
122
123 /* we only want to try loading the guspat once. */
124 sample_patch->loaded = 1;
125
126 if ((guspat = _WM_load_gus_pat(sample_patch->filename, _WM_fix_release)) == NULL) {
127 return (-1);
128 }
129
130 if (_WM_auto_amp) {
131 int16_t tmp_max = 0;
132 int16_t tmp_min = 0;
133 int16_t samp_max = 0;
134 int16_t samp_min = 0;
135 tmp_sample = guspat;
136 do {
137 samp_max = 0;
138 samp_min = 0;
139 for (i = 0; i < (tmp_sample->data_length >> 10); i++) {
140 if (tmp_sample->data[i] > samp_max)
141 samp_max = tmp_sample->data[i];
142 if (tmp_sample->data[i] < samp_min)
143 samp_min = tmp_sample->data[i];
144 }
145 if (samp_max > tmp_max)
146 tmp_max = samp_max;
147 if (samp_min < tmp_min)
148 tmp_min = samp_min;
149 tmp_sample = tmp_sample->next;
150 } while (tmp_sample);
151 if (_WM_auto_amp_with_amp) {
152 if (tmp_max >= -tmp_min) {
153 sample_patch->amp = (sample_patch->amp
154 * ((32767 << 10) / tmp_max)) >> 10;
155 } else {
156 sample_patch->amp = (sample_patch->amp
157 * ((32768 << 10) / -tmp_min)) >> 10;
158 }
159 } else {
160 if (tmp_max >= -tmp_min) {
161 sample_patch->amp = (32767 << 10) / tmp_max;
162 } else {
163 sample_patch->amp = (32768 << 10) / -tmp_min;
164 }
165 }
166 }
167
168 sample_patch->first_sample = guspat;
169
170 if (sample_patch->patchid & 0x0080) {
171 if (!(sample_patch->keep & SAMPLE_LOOP)) {
172 do {
173 guspat->modes &= 0xFB;
174 guspat = guspat->next;
175 } while (guspat);
176 }
177 guspat = sample_patch->first_sample;
178 if (!(sample_patch->keep & SAMPLE_ENVELOPE)) {
179 do {
180 guspat->modes &= 0xBF;
181 guspat = guspat->next;
182 } while (guspat);
183 }
184 guspat = sample_patch->first_sample;
185 }
186
187 if (sample_patch->patchid == 47) {
188 do {
189 if (!(guspat->modes & SAMPLE_LOOP)) {
190 for (i = 3; i < 6; i++) {
191 guspat->env_target[i] = guspat->env_target[2];
192 guspat->env_rate[i] = guspat->env_rate[2];
193 }
194 }
195 guspat = guspat->next;
196 } while (guspat);
197 guspat = sample_patch->first_sample;
198 }
199
200 do {
201 if ((sample_patch->remove & SAMPLE_SUSTAIN)
202 && (guspat->modes & SAMPLE_SUSTAIN)) {
203 guspat->modes ^= SAMPLE_SUSTAIN;
204 }
205 if ((sample_patch->remove & SAMPLE_CLAMPED)
206 && (guspat->modes & SAMPLE_CLAMPED)) {
207 guspat->modes ^= SAMPLE_CLAMPED;
208 }
209 if (sample_patch->keep & SAMPLE_ENVELOPE) {
210 guspat->modes |= SAMPLE_ENVELOPE;
211 }
212
213 for (i = 0; i < 6; i++) {
214 if (guspat->modes & SAMPLE_ENVELOPE) {
215 if (sample_patch->env[i].set & 0x02) {
216 guspat->env_target[i] = 16448
217 * (int32_t) (255.0f * sample_patch->env[i].level);
218 }
219 if (sample_patch->env[i].set & 0x01) {
220 guspat->env_rate[i] = (int32_t) (4194303.0f
221 / ((float) _WM_SampleRate
222 * (sample_patch->env[i].time / 1000.0f)));
223 }
224 } else {
225 guspat->env_target[i] = 4194303;
226 guspat->env_rate[i] = (int32_t) (4194303.0f
227 / ((float) _WM_SampleRate * env_time_table[63]));
228 }
229 }
230
231 guspat = guspat->next;
232 } while (guspat);
233 return (0);
234 }
235