git.haldean.org qb / 757d900
scrub controls, no segfaults haldean 5 months ago
1 changed file(s) with 47 addition(s) and 23 deletion(s). Raw diff Collapse all Expand all
2020 context::context() {
2121 _nodes.push_back(std::make_shared<qb::audio_node>(this, "test/coc-mono.wav"));
2222 qb::theme::setdefault();
23 ImGui::GetIO().KeyRepeatRate = 1.0f / _framerate;
2324 }
2425
2526 int context::frame2pixel(double frame) {
4445 ImGui::Begin("MainWindow", nullptr,
4546 ImGuiWindowFlags_NoDecoration);
4647
47 if (!audioinit) {
48 initaudio();
49 }
50 if (audioinit) {
51 if (ImGui::IsKeyPressed(SAPP_KEYCODE_SPACE, /* repeat */ false)) {
52 playing = !playing;
53 }
54 pushaudio();
55 }
56
5748 double minframe = 0;
5849 double maxframe = 0;
5950 for (const auto &n : _nodes) {
6051 minframe = std::min(minframe, (double) n->minframe());
6152 maxframe = std::max(maxframe, (double) n->maxframe());
53 }
54
55 if (!audioinit) {
56 initaudio();
57 }
58 if (audioinit) {
59 if (ImGui::IsKeyPressed(SAPP_KEYCODE_SPACE, /* repeat */ false)) {
60 playing = !playing;
61 }
62 if (!playing) {
63 if (ImGui::IsKeyPressed(SAPP_KEYCODE_LEFT)) {
64 playhead = floor(playhead) - 1.0;
65 } else if (ImGui::IsKeyPressed(SAPP_KEYCODE_RIGHT)) {
66 playhead = floor(playhead) + 1.0;
67 } else if (ImGui::IsKeyPressed(SAPP_KEYCODE_UP)) {
68 playhead = minframe;
69 } else if (ImGui::IsKeyPressed(SAPP_KEYCODE_DOWN)) {
70 playhead = maxframe;
71 }
72 } else {
73 if (playhead > maxframe) {
74 playing = false;
75 }
76 }
77 pushaudio();
6278 }
6379
6480 if (ImGui::IsMouseDragging(ImGuiMouseButton_Middle)) {
130146
131147 const int samplerate = audiosource->data()->getSampleRate();
132148 const double sampleperframe = (double) samplerate / (double) _framerate;
149 const std::vector<float> &s = audiosource->packed();
133150
134151 if (!playing) {
135152 if ((int) playhead == playedframe) {
137154 }
138155 const double firstsample = floor(playhead) * sampleperframe;
139156 const size_t s0 = (size_t) floor(firstsample);
140
141 const int topush = (int) sampleperframe;
142 const int pushed =
143 saudio_push(&audiosource->packed()[s0], topush);
157 if (s0 >= s.size()) {
158 return;
159 }
160 const int topush = std::min((int) sampleperframe, (int) (s.size() - s0));
161 const int pushed = saudio_push(&s[s0], topush);
144162 playedframe = (int) playhead;
145163 pushedsample = (int64_t) (s0 + sampleperframe - 1);
146164
147165 } else {
148
149166 const double elapsed = ImGui::GetIO().DeltaTime;
150167 playhead += elapsed * _framerate;
151168
152169 const int64_t nextsample = (int64_t) floor(playhead * sampleperframe);
153170
154171 // buffer 125ms of audio
155 const int buffersamples = samplerate / 8;
172 const int64_t buffersamples = samplerate / 8;
156173 // add to buffer whenever we have less than 50ms left in the buffer
157 const int bufferrefill = samplerate / 20;
158
174 const int64_t bufferrefill = samplerate / 20;
175
176 int64_t fillfrom = -1;
177 int64_t dist = pushedsample - nextsample;
159178 if (pushedsample < 0) {
160 int pushed = saudio_push(&audiosource->packed()[nextsample], buffersamples);
161 pushedsample = nextsample + pushed;
162 } else if (pushedsample - nextsample < bufferrefill) {
163 int pushed = saudio_push(&audiosource->packed()[pushedsample + 1], buffersamples);
164 pushedsample += pushed;
179 fillfrom = nextsample;
180 } else if (dist < bufferrefill) {
181 fillfrom = pushedsample + 1;
182 }
183
184 if (fillfrom >= 0 && (size_t) fillfrom < s.size()) {
185 const int fillamount =
186 (int) std::min(buffersamples, (int64_t)(s.size() - fillfrom - 1));
187 const int pushed = saudio_push(&s[fillfrom], fillamount);
188 pushedsample = fillfrom + pushed;
165189 }
166190 }
167191 }