Skip to content

Commit bc84eb6

Browse files
committed
Clean up
1 parent ed05a46 commit bc84eb6

File tree

2 files changed

+98
-25
lines changed

2 files changed

+98
-25
lines changed

shaders/audio.comp

Lines changed: 73 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,83 @@ layout( push_constant ) uniform PushConstants
1010
{
1111
float time;
1212
int samples;
13-
float amplitude;
1413
float frequency;
14+
float a;
15+
float b;
16+
float c;
1517
} constants;
1618

19+
float supersaw(float frequency, float t, float detune, int voices) {
20+
float sum = 0.0;
21+
for (int i = 0; i < voices; i++) {
22+
float offset = (float(i) / float(voices) - 0.5) * detune;
23+
float freq = frequency * (1.0 + offset);
24+
float phase = mod(freq * t, 1.0);
25+
sum += 2.0 * phase - 1.0;
26+
}
27+
return sum / float(voices);
28+
}
29+
30+
float TAU = 3.14159 * 2;
31+
float additive(float frequency, float t) {
32+
float sum = 0.0;
33+
// Harmonic, Amplitude pairs
34+
sum += 1.0 * sin(TAU * frequency * 1.0 * t);
35+
sum += 0.5 * sin(TAU * frequency * 2.0 * t);
36+
sum += 0.25 * sin(TAU * frequency * 3.0 * t);
37+
sum += 0.125 * sin(TAU * frequency * 4.0 * t);
38+
return sum;
39+
}
40+
41+
float morph(float frequency, float t, float mix) {
42+
float phase = frequency * t;
43+
float sine = sin(TAU * phase);
44+
float saw = 2.0 * mod(phase, 1.0) - 1.0;
45+
return sine * (1.0 - mix) + saw * mix;
46+
}
47+
48+
float sawtooth(float frequency, float t) {
49+
float phase = mod(frequency * t, 1.0);
50+
return 2.0 * phase - 1.0;
51+
}
52+
// Stereo supersaw with phase offset
53+
vec2 supersaw_stereo(float frequency, float t, float detune, int voices, float stereo_width) {
54+
float left = 0.0;
55+
float right = 0.0;
56+
57+
for (int i = 0; i < voices; i++) {
58+
float offset = (float(i) / float(voices) - 0.5) * detune;
59+
float freq = frequency * (1.0 + offset);
60+
float phase = mod(freq * t, 1.0);
61+
62+
// Pan each voice differently
63+
float pan = float(i) / float(voices - 1); // 0 to 1
64+
float l_amp = cos(pan * 1.5708) * stereo_width + (1.0 - stereo_width);
65+
float r_amp = sin(pan * 1.5708) * stereo_width + (1.0 - stereo_width);
66+
67+
float saw = 2.0 * phase - 1.0;
68+
left += saw * l_amp;
69+
right += saw * r_amp;
70+
}
71+
72+
return vec2(left, right) / float(voices);
73+
}
74+
1775
vec2 func(float t) {
18-
float tau = 2.0 * 3.14169;
19-
float n = sin( tau * constants.frequency * t );
20-
float m = n * pow( 1.0 - t, 3.0 );
21-
float a = ( sin( t * tau ) / 2.0 - 0.5 ) * m * constants.amplitude;
22-
float b = ( sin( t * tau + tau * 0.5 ) / 2.0 - 0.5 ) * m * constants.amplitude;
23-
return vec2(a, b);
76+
77+
float audio = sawtooth(constants.frequency, t);
78+
// audio = supersaw(constants.frequency, t, constants.a, int(constants.b * 9));
79+
audio = additive(constants.frequency, t);
80+
audio = morph(constants.frequency, t, constants.a);
81+
return supersaw_stereo(constants.frequency, t, constants.a, int(9 * constants.b), constants.c);
82+
return vec2(audio);
83+
84+
// float tau = 2.0 * 3.14169;
85+
// float n = sin( tau * constants.frequency * t );
86+
// float m = n * pow( 1.0 - t, 3.0 );
87+
// float a = ( sin( t * tau * constants.a ) / 2.0 * constants.b- 0.5 ) * m;
88+
// float b = ( sin( t * tau + tau * 0.5 ) / 2.0 - 0.5 ) * m;
89+
// return vec2(a, b);
2490
}
2591

2692
void main()

src/main.rs

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ struct AudioController {
3535
b: f32,
3636
c: f32,
3737
audio: Vec<AudioPacket>,
38+
repeat: bool
3839
}
3940

4041
impl AudioController {
@@ -96,7 +97,6 @@ struct App
9697
{
9798
player: AudioPlayer,
9899
controller: Arc<Mutex<AudioController>>,
99-
samples_per_second: u32,
100100
pipeline: PipelineKey,
101101
buffer: Buffer,
102102
frame_index: u32,
@@ -107,8 +107,10 @@ struct App
107107
struct PushConstants {
108108
time: f32,
109109
samples: u32,
110-
amplitude: f32,
111-
frequency: f32
110+
frequency: f32,
111+
a: f32,
112+
b: f32,
113+
c: f32,
112114
}
113115

114116
impl App {
@@ -118,6 +120,7 @@ impl App {
118120
a: 1.0,
119121
b: 0.0,
120122
c: 1.0,
123+
repeat: false,
121124
engine_start_time: SystemTime::now(),
122125
play_start_time: SystemTime::now(),
123126
frequency: 440.,
@@ -158,7 +161,6 @@ impl App {
158161
);
159162

160163
Self {
161-
samples_per_second: 1000,
162164
player,
163165
controller,
164166
pipeline,
@@ -188,8 +190,10 @@ impl RenderComponent for App {
188190
let push_constants = PushConstants {
189191
time: 0.0,
190192
samples: BUFFER_SAMPLES as u32,
191-
amplitude: lock.a,
192-
frequency: lock.frequency
193+
frequency: lock.frequency,
194+
a: lock.a,
195+
b: lock.b,
196+
c: lock.c,
193197
};
194198
ctx.command_buffer.push_constants(
195199
&pipeline,
@@ -226,23 +230,11 @@ impl GuiComponent for App {
226230
fn gui(&mut self, _: &mut GuiHandler, ctx: &Context) {
227231
let mut lock = self.controller.lock().unwrap();
228232
egui::CentralPanel::default().show(ctx, |ui| {
229-
if ui.button("play").clicked() {
230-
lock.play_start_time = SystemTime::now() + Duration::new(0, 5000000);
231-
}
232-
ui.add(Slider::new(&mut lock.volume, 0.0..=1.0));
233-
ui.add(Slider::new(&mut lock.frequency, 0.0..=1000.0));
234-
ui.add(Slider::new(&mut lock.a, 0.0..=2.0));
235-
ui.add(Slider::new(&mut lock.b, -1.0..=1.0));
236-
ui.add(Slider::new(&mut lock.c, 0.0..=2.0));
237-
238-
ui.label("Samples per second");
239-
ui.add(Slider::new(&mut self.samples_per_second, 100..=100000));
240233

241234
if let Some(audio) = lock.audio.first() {
242235
Plot::new("audio_plot")
243236
.view_aspect(2.0)
244237
.show(ui, |plot_ui| {
245-
// let total_samples = (duration * self.samples_per_second as f32) as i32;
246238
let total_samples = BUFFER_SAMPLES;
247239
// Convert audio samples to plot points
248240
let points = (0..total_samples)
@@ -255,6 +247,21 @@ impl GuiComponent for App {
255247
plot_ui.line(Line::new("audio", plot_points));
256248
});
257249
}
250+
251+
if ui.button("play").clicked() {
252+
lock.play_start_time = SystemTime::now() + Duration::new(0, 5000000);
253+
}
254+
ui.checkbox(&mut lock.repeat, "");
255+
if lock.repeat && SystemTime::now().duration_since(lock.play_start_time).unwrap().as_secs_f64() > 0.9 {
256+
lock.play_start_time = SystemTime::now() + Duration::new(0, 0);
257+
}
258+
259+
ui.style_mut().spacing.slider_width = 190.;
260+
ui.add(Slider::new(&mut lock.volume, 0.0..=1.0).text("Volume"));
261+
ui.add(Slider::new(&mut lock.frequency, 0.0..=1000.0).text("Frequency"));
262+
ui.add(Slider::new(&mut lock.a, 0.0..=2.0).text("a"));
263+
ui.add(Slider::new(&mut lock.b, -1.0..=1.0).text("b"));
264+
ui.add(Slider::new(&mut lock.c, 0.0..=2.0).text("c"));
258265
});
259266

260267
// The gui isn't the correct call for this, but there's no other place right now

0 commit comments

Comments
 (0)