| 117 | } |
| 118 | |
| 119 | void AudioStreamPreviewGenerator::_preview_thread(void *p_preview) { |
| 120 | Thread::set_name("AudioStreamPreviewGenerator"); |
| 121 | |
| 122 | Preview *preview = static_cast<Preview *>(p_preview); |
| 123 | |
| 124 | float muxbuff_chunk_s = 0.25; |
| 125 | |
| 126 | int mixbuff_chunk_frames = AudioServer::get_singleton()->get_mix_rate() * muxbuff_chunk_s; |
| 127 | |
| 128 | Vector<AudioFrame> mix_chunk; |
| 129 | mix_chunk.resize(mixbuff_chunk_frames); |
| 130 | |
| 131 | int frames_total = AudioServer::get_singleton()->get_mix_rate() * preview->preview->length; |
| 132 | int frames_todo = frames_total; |
| 133 | |
| 134 | preview->playback->start(); |
| 135 | |
| 136 | while (frames_todo) { |
| 137 | int ofs_write = uint64_t(frames_total - frames_todo) * uint64_t(preview->preview->preview.size() / 2) / uint64_t(frames_total); |
| 138 | int to_read = MIN(frames_todo, mixbuff_chunk_frames); |
| 139 | int to_write = uint64_t(to_read) * uint64_t(preview->preview->preview.size() / 2) / uint64_t(frames_total); |
| 140 | to_write = MIN(to_write, (preview->preview->preview.size() / 2) - ofs_write); |
| 141 | |
| 142 | preview->playback->mix(mix_chunk.ptrw(), 1.0, to_read); |
| 143 | |
| 144 | for (int i = 0; i < to_write; i++) { |
| 145 | float max = -1000; |
| 146 | float min = 1000; |
| 147 | int from = uint64_t(i) * to_read / to_write; |
| 148 | int to = (uint64_t(i) + 1) * to_read / to_write; |
| 149 | to = MIN(to, to_read); |
| 150 | from = MIN(from, to_read - 1); |
| 151 | if (to == from) { |
| 152 | to = from + 1; |
| 153 | } |
| 154 | |
| 155 | for (int j = from; j < to; j++) { |
| 156 | max = MAX(max, mix_chunk[j].left); |
| 157 | max = MAX(max, mix_chunk[j].right); |
| 158 | |
| 159 | min = MIN(min, mix_chunk[j].left); |
| 160 | min = MIN(min, mix_chunk[j].right); |
| 161 | } |
| 162 | |
| 163 | uint8_t pfrom = CLAMP((min * 0.5 + 0.5) * 255, 0, 255); |
| 164 | uint8_t pto = CLAMP((max * 0.5 + 0.5) * 255, 0, 255); |
| 165 | |
| 166 | preview->preview->preview.write[(ofs_write + i) * 2 + 0] = pfrom; |
| 167 | preview->preview->preview.write[(ofs_write + i) * 2 + 1] = pto; |
| 168 | } |
| 169 | |
| 170 | frames_todo -= to_read; |
| 171 | callable_mp(singleton, &AudioStreamPreviewGenerator::_update_emit).call_deferred(preview->id); |
| 172 | } |
| 173 | |
| 174 | preview->preview->version++; |
| 175 | |
| 176 | preview->playback->stop(); |
nothing calls this directly
no test coverage detected