diff options
-rw-r--r-- | source/saw/main.c | 83 |
1 files changed, 25 insertions, 58 deletions
diff --git a/source/saw/main.c b/source/saw/main.c index 63e8a4c..1a51aeb 100644 --- a/source/saw/main.c +++ b/source/saw/main.c @@ -205,7 +205,6 @@ typedef struct { saw_da_f32_t outline; f64 begin; f64 end; - f64 tail; f64 crossfade; f64 base_frequency; f64 volume; @@ -660,9 +659,6 @@ static void saw_audio_render(void) { case INSTRUMENT_SAMPLER: { saw_sampler_t *sam = &track->sampler; - if (sam->begin + sam->crossfade + TIME_EPS >= sam->end) - break; - f64 frequency = saw_voices[n].frequency; f64 amplitude = saw_voices[n].amplitude; @@ -677,32 +673,33 @@ static void saw_audio_render(void) { sustain, duration, release); - f64 crossfade = sam->crossfade; - f64 sample_begin = sam->begin; - f64 sample_end = sam->end; + if (frequency < TIME_EPS) + break; + + f64 crossfade = (sam->crossfade * sam->base_frequency) / + frequency; + f64 sample_begin = (sam->begin * sam->base_frequency) / + frequency; + f64 sample_end = (sam->end * sam->base_frequency) / + frequency; f64 sample_duration = sample_end - sample_begin - crossfade; - f64 sample_tail = sam->tail; - f64 body_end = duration + crossfade; - f64 tail_begin = duration; - f64 tail_end = tail_begin + sample_tail; + f64 body_end = duration + release; if (t <= body_end) { // Play the body // f64 q = t; - assert(sample_duration > TIME_EPS); - while (q >= sample_duration) - q -= sample_duration; + if (sample_duration > TIME_EPS) + q -= sample_duration * floor(q / sample_duration); q += sample_begin; f64 u0 = 1.; - if (t > tail_begin && crossfade > TIME_EPS) - u0 = 1. - (t - tail_begin) / crossfade; - if (t >= sample_duration && q < crossfade && - crossfade > TIME_EPS) { + if (sample_duration > TIME_EPS && + crossfade > TIME_EPS && t >= sample_duration && + q < crossfade) { // Play the body crossfade // @@ -739,30 +736,9 @@ static void saw_audio_render(void) { } } - if (t >= tail_begin && t <= tail_end) { - // Play the tail - // - - f64 q = t - tail_begin; - - f64 u = 1.; - if (q < crossfade && crossfade > TIME_EPS) - u = q / crossfade; - - f64 r = sample_end + q; - i64 k = (i64) floor(r * SAMPLE_RATE + .5); - - saw_playback_temp[i * CHANNEL_COUNT] += - (f32) (saw_sampler(sam, 0, frequency, k) * a * u * - GLOBAL_VOLUME); - saw_playback_temp[i * CHANNEL_COUNT + 1] += - (f32) (saw_sampler(sam, 1, frequency, k) * a * u * - GLOBAL_VOLUME); - } - saw_voices[n].time++; - if (t > duration + release) { + if (t >= duration + release) { saw_voices[n].enabled = 0; regroup_voices = 1; } @@ -1728,7 +1704,6 @@ static void saw_ui_choose_instrument(saw_track_t *track, i64 x0, track->sampler.begin = 0.; track->sampler.end = 1.; - track->sampler.tail = .2; track->sampler.crossfade = .01; track->sampler.base_frequency = 440.; track->sampler.volume = .5; @@ -1888,15 +1863,12 @@ static void saw_ui_sampler(saw_sampler_t *sampler, i64 x0, i64 y0, w, text_height, TINT_WHITE, SZ("End"), 100000, 0., 60., &sampler->end); saw_ui_value_float(x, y0 + height - sample_height - text_height * 3, - w, text_height, TINT_WHITE, SZ("Tail"), 100000, - 0., 60., &sampler->tail); - saw_ui_value_float(x, y0 + height - sample_height - text_height * 4, w, text_height, TINT_WHITE, SZ("Crossfade"), 100000, 0., 60., &sampler->crossfade); - saw_ui_value_float(x, y0 + height - sample_height - text_height * 5, + saw_ui_value_float(x, y0 + height - sample_height - text_height * 4, w, text_height, TINT_WHITE, SZ("Base freq."), 500, 1., 44100., &sampler->base_frequency); - saw_ui_value_float(x, y0 + height - sample_height - text_height * 6, + saw_ui_value_float(x, y0 + height - sample_height - text_height * 5, w, text_height, TINT_WHITE, SZ("Volume."), 10000, 0., 2., &sampler->volume); @@ -1906,22 +1878,21 @@ static void saw_ui_sampler(saw_sampler_t *sampler, i64 x0, i64 y0, nvgTextAlign(saw_nvg, NVG_ALIGN_LEFT | NVG_ALIGN_BASELINE); nvgText(saw_nvg, x, frame_height - y0 - height + sample_height + - (text_height * 15) / 2, + (text_height * 13) / 2, "Envelope", NULL); - saw_ui_value_float(x, y0 + height - sample_height - text_height * 9, + saw_ui_value_float(x, y0 + height - sample_height - text_height * 8, w, text_height, TINT_WHITE, SZ("Sustain"), 10000, 0., 1., &sampler->envelope.sustain); - saw_ui_value_float(x, - y0 + height - sample_height - text_height * 10, + saw_ui_value_float(x, y0 + height - sample_height - text_height * 9, w, text_height, TINT_WHITE, SZ("Attack"), 100000, 0., 6., &sampler->envelope.attack); saw_ui_value_float(x, - y0 + height - sample_height - text_height * 11, + y0 + height - sample_height - text_height * 10, w, text_height, TINT_WHITE, SZ("Decay"), 100000, 0., 6., &sampler->envelope.decay); saw_ui_value_float(x, - y0 + height - sample_height - text_height * 12, + y0 + height - sample_height - text_height * 11, w, text_height, TINT_WHITE, SZ("Release"), 100000, 0., 6., &sampler->envelope.release); } @@ -2848,12 +2819,11 @@ static void saw_init(void) { sam->outline.values[i] = fabs(v[k] + v[k + 1]) * .5; } - i64 begin, end, tail, crossfade, bfreq, volume, sustain, - attack, decay, release; + i64 begin, end, crossfade, bfreq, volume, sustain, attack, + decay, release; SCAN_(" begin %lld", 1, &begin); SCAN_(" end %lld", 1, &end); - SCAN_(" tail %lld", 1, &tail); SCAN_(" crossfade %lld", 1, &crossfade); SCAN_(" base_frequency %lld", 1, &bfreq); SCAN_(" volume %lld", 1, &volume); @@ -2864,7 +2834,6 @@ static void saw_init(void) { sam->begin = begin * .0001; sam->end = end * .0001; - sam->tail = tail * .0001; sam->crossfade = crossfade * .0001; sam->base_frequency = bfreq * .0001; sam->volume = volume * .0001; @@ -3152,8 +3121,6 @@ static void saw_cleanup(void) { (i64) floor(sam->begin * 10000 + .5)); fprintf(f, "end %lld\n", (i64) floor(sam->end * 10000 + .5)); - fprintf(f, "tail %lld\n", - (i64) floor(sam->tail * 10000 + .5)); fprintf(f, "crossfade %lld\n", (i64) floor(sam->crossfade * 10000 + .5)); fprintf(f, "base_frequency %lld\n", |