scrub controls, no segfaults
haldean
1 year, 9 months ago
20 | 20 | context::context() { |
21 | 21 | _nodes.push_back(std::make_shared<qb::audio_node>(this, "test/coc-mono.wav")); |
22 | 22 | qb::theme::setdefault(); |
23 | ImGui::GetIO().KeyRepeatRate = 1.0f / _framerate; | |
23 | 24 | } |
24 | 25 | |
25 | 26 | int context::frame2pixel(double frame) { |
44 | 45 | ImGui::Begin("MainWindow", nullptr, |
45 | 46 | ImGuiWindowFlags_NoDecoration); |
46 | 47 | |
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 | ||
57 | 48 | double minframe = 0; |
58 | 49 | double maxframe = 0; |
59 | 50 | for (const auto &n : _nodes) { |
60 | 51 | minframe = std::min(minframe, (double) n->minframe()); |
61 | 52 | 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(); | |
62 | 78 | } |
63 | 79 | |
64 | 80 | if (ImGui::IsMouseDragging(ImGuiMouseButton_Middle)) { |
130 | 146 | |
131 | 147 | const int samplerate = audiosource->data()->getSampleRate(); |
132 | 148 | const double sampleperframe = (double) samplerate / (double) _framerate; |
149 | const std::vector<float> &s = audiosource->packed(); | |
133 | 150 | |
134 | 151 | if (!playing) { |
135 | 152 | if ((int) playhead == playedframe) { |
137 | 154 | } |
138 | 155 | const double firstsample = floor(playhead) * sampleperframe; |
139 | 156 | 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); | |
144 | 162 | playedframe = (int) playhead; |
145 | 163 | pushedsample = (int64_t) (s0 + sampleperframe - 1); |
146 | 164 | |
147 | 165 | } else { |
148 | ||
149 | 166 | const double elapsed = ImGui::GetIO().DeltaTime; |
150 | 167 | playhead += elapsed * _framerate; |
151 | 168 | |
152 | 169 | const int64_t nextsample = (int64_t) floor(playhead * sampleperframe); |
153 | 170 | |
154 | 171 | // buffer 125ms of audio |
155 | const int buffersamples = samplerate / 8; | |
172 | const int64_t buffersamples = samplerate / 8; | |
156 | 173 | // 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; | |
159 | 178 | 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; | |
165 | 189 | } |
166 | 190 | } |
167 | 191 | } |