You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

401 lines
15KB

  1. /* Copyright 2013-2019 Matt Tytel
  2. *
  3. * vital is free software: you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation, either version 3 of the License, or
  6. * (at your option) any later version.
  7. *
  8. * vital is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with vital. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #include "file_source.h"
  17. FileSource::FileSourceKeyframe::FileSourceKeyframe(SampleBuffer* sample_buffer) {
  18. sample_buffer_ = sample_buffer;
  19. start_position_ = 0.0f;
  20. window_fade_ = 1.0f;
  21. window_size_ = vital::WaveFrame::kWaveformSize;
  22. fade_style_ = kWaveBlend;
  23. phase_style_ = kNone;
  24. overridden_phase_ = nullptr;
  25. interpolate_from_frame_ = nullptr;
  26. interpolate_to_frame_ = nullptr;
  27. }
  28. void FileSource::FileSourceKeyframe::copy(const WavetableKeyframe* keyframe) {
  29. const FileSourceKeyframe* source = dynamic_cast<const FileSourceKeyframe*>(keyframe);
  30. VITAL_ASSERT(source);
  31. start_position_ = source->start_position_;
  32. window_fade_ = source->window_fade_;
  33. }
  34. void FileSource::FileSourceKeyframe::interpolate(const WavetableKeyframe* from_keyframe,
  35. const WavetableKeyframe* to_keyframe,
  36. float t) {
  37. const FileSourceKeyframe* from = dynamic_cast<const FileSourceKeyframe*>(from_keyframe);
  38. const FileSourceKeyframe* to = dynamic_cast<const FileSourceKeyframe*>(to_keyframe);
  39. VITAL_ASSERT(from);
  40. VITAL_ASSERT(to);
  41. start_position_ = linearTween(from->start_position_, to->start_position_, t);
  42. window_fade_ = linearTween(from->window_fade_, to->window_fade_, t);
  43. }
  44. force_inline float FileSource::FileSourceKeyframe::getScaledInterpolatedSample(float position) {
  45. const float* buffer = getCubicInterpolationBuffer();
  46. float clamped_position = vital::utils::clamp(position, 0.0f, sample_buffer_->size - 1);
  47. int start_index = clamped_position;
  48. float t = clamped_position - start_index;
  49. vital::matrix interpolation_matrix = vital::utils::getCatmullInterpolationMatrix(t);
  50. vital::matrix value_matrix = vital::utils::getValueMatrix(buffer, start_index);
  51. value_matrix.transpose();
  52. return interpolation_matrix.multiplyAndSumRows(value_matrix)[0];
  53. }
  54. float FileSource::FileSourceKeyframe::getNormalizationScale() {
  55. const float* buffer = getDataBuffer();
  56. if (buffer == nullptr)
  57. return 1.0f;
  58. double cycles_in = start_position_ / window_size_;
  59. int cycle = cycles_in;
  60. double start_index = cycle * window_size_;
  61. float max = 0.0f;
  62. float min = 0.0f;
  63. for (int i = 0; i < vital::WaveFrame::kWaveformSize; ++i) {
  64. double t = i / (vital::WaveFrame::kWaveformSize * 1.0);
  65. double position = std::min<double>(start_index + t * window_size_, sample_buffer_->size - 1);
  66. int from_index = position;
  67. int to_index = std::min(sample_buffer_->size - 1, from_index + 1);
  68. VITAL_ASSERT(from_index >= 0 && from_index < sample_buffer_->size);
  69. VITAL_ASSERT(to_index >= 0 && to_index < sample_buffer_->size);
  70. float from_sample = buffer[from_index];
  71. float to_sample = buffer[to_index];
  72. max = std::max(from_sample, max);
  73. max = std::max(to_sample, max);
  74. min = std::min(from_sample, min);
  75. min = std::min(to_sample, min);
  76. }
  77. return 2.0f / std::max(max - min, 0.001f);
  78. }
  79. void FileSource::FileSourceKeyframe::render(vital::WaveFrame* wave_frame) {
  80. if (sample_buffer_->size <= 0) {
  81. wave_frame->clear();
  82. return;
  83. }
  84. if (fade_style_ == kWaveBlend)
  85. renderWaveBlend(wave_frame);
  86. else if (fade_style_ == kNoInterpolate)
  87. renderNoInterpolate(wave_frame);
  88. else if (fade_style_ == kTimeInterpolate)
  89. renderTimeInterpolate(wave_frame);
  90. else if (fade_style_ == kFreqInterpolate)
  91. renderFreqInterpolate(wave_frame);
  92. if (phase_style_ == kClear || phase_style_ == kVocode) {
  93. for (int i = 0; i < vital::WaveFrame::kWaveformSize; ++i) {
  94. float amplitude = std::abs(wave_frame->frequency_domain[i]);
  95. wave_frame->frequency_domain[i] = std::polar(amplitude, overridden_phase_[i]);
  96. }
  97. }
  98. wave_frame->toTimeDomain();
  99. }
  100. void FileSource::FileSourceKeyframe::renderWaveBlend(vital::WaveFrame* wave_frame) {
  101. double window_ratio = window_size_ / vital::WaveFrame::kWaveformSize;
  102. int waveform_middle = vital::WaveFrame::kWaveformSize / 2;
  103. int start_index = start_position_ / window_ratio + window_size_ / 2.0f + waveform_middle;
  104. start_index = start_index % vital::WaveFrame::kWaveformSize;
  105. for (int i = 0; i < vital::WaveFrame::kWaveformSize; ++i) {
  106. double t = i / (vital::WaveFrame::kWaveformSize * 1.0);
  107. double position = start_position_ + t * window_size_;
  108. int write_index = (start_index + i) % vital::WaveFrame::kWaveformSize;
  109. wave_frame->time_domain[write_index] = getScaledInterpolatedSample(position);
  110. }
  111. int fade_samples = window_fade_ * vital::WaveFrame::kWaveformSize;
  112. double fade_size = fade_samples * window_ratio;
  113. for (int i = 0; i < fade_samples; ++i) {
  114. double t = i / (fade_samples - 1.0f);
  115. double fade = 0.5 + 0.5 * cos(vital::kPi * t);
  116. int write_index = (start_index + i) % vital::WaveFrame::kWaveformSize;
  117. double position = start_position_ + window_size_ + t * fade_size;
  118. double existing_value = wave_frame->time_domain[write_index];
  119. double fade_value = getScaledInterpolatedSample(position);
  120. wave_frame->time_domain[write_index] = linearTween(existing_value, fade_value, fade);
  121. }
  122. wave_frame->toFrequencyDomain();
  123. }
  124. void FileSource::FileSourceKeyframe::renderNoInterpolate(vital::WaveFrame* wave_frame) {
  125. double cycles_in = start_position_ / window_size_;
  126. int cycle = cycles_in;
  127. double start_index = cycle * window_size_;
  128. for (int i = 0; i < vital::WaveFrame::kWaveformSize; ++i) {
  129. double t = i / (vital::WaveFrame::kWaveformSize * 1.0);
  130. double position = start_index + t * window_size_;
  131. wave_frame->time_domain[i] = getScaledInterpolatedSample(position);
  132. }
  133. wave_frame->toFrequencyDomain();
  134. }
  135. void FileSource::FileSourceKeyframe::renderTimeInterpolate(vital::WaveFrame* wave_frame) {
  136. double cycles_in = start_position_ / window_size_;
  137. int from_cycle = cycles_in;
  138. int to_cycle = from_cycle + 1;
  139. float transition = cycles_in - from_cycle;
  140. double start_index_from = from_cycle * window_size_;
  141. double start_index_to = to_cycle * window_size_;
  142. for (int i = 0; i < vital::WaveFrame::kWaveformSize; ++i) {
  143. double t = i / (vital::WaveFrame::kWaveformSize * 1.0);
  144. double from_position = start_index_from + t * window_size_;
  145. double to_position = start_index_to + t * window_size_;
  146. float from_sample = getScaledInterpolatedSample(from_position);
  147. float to_sample = getScaledInterpolatedSample(to_position);
  148. wave_frame->time_domain[i] = vital::utils::interpolate(from_sample, to_sample, transition);
  149. }
  150. wave_frame->toFrequencyDomain();
  151. }
  152. void FileSource::FileSourceKeyframe::renderFreqInterpolate(vital::WaveFrame* wave_frame) {
  153. double cycles_in = start_position_ / window_size_;
  154. int from_cycle = cycles_in;
  155. int to_cycle = from_cycle + 1;
  156. float transition = cycles_in - from_cycle;
  157. double start_index_from = from_cycle * window_size_;
  158. double start_index_to = to_cycle * window_size_;
  159. vital::WaveFrame* from_wave_frame = interpolate_from_frame_->wave_frame();
  160. vital::WaveFrame* to_wave_frame = interpolate_to_frame_->wave_frame();
  161. for (int i = 0; i < vital::WaveFrame::kWaveformSize; ++i) {
  162. double t = i / (vital::WaveFrame::kWaveformSize * 1.0);
  163. double from_position = start_index_from + t * window_size_;
  164. double to_position = start_index_to + t * window_size_;
  165. from_wave_frame->time_domain[i] = getScaledInterpolatedSample(from_position);
  166. to_wave_frame->time_domain[i] = getScaledInterpolatedSample(to_position);
  167. }
  168. from_wave_frame->toFrequencyDomain();
  169. to_wave_frame->toFrequencyDomain();
  170. interpolate_from_frame_->linearFrequencyInterpolate(from_wave_frame, to_wave_frame, transition);
  171. wave_frame->copy(interpolate_from_frame_->wave_frame());
  172. }
  173. json FileSource::FileSourceKeyframe::stateToJson() {
  174. json data = WavetableKeyframe::stateToJson();
  175. data["start_position"] = start_position_;
  176. data["window_fade"] = window_fade_;
  177. data["window_size"] = window_size_;
  178. return data;
  179. }
  180. void FileSource::FileSourceKeyframe::jsonToState(json data) {
  181. WavetableKeyframe::jsonToState(data);
  182. start_position_ = data["start_position"];
  183. window_fade_ = data["window_fade"];
  184. window_size_ = data["window_size"];
  185. }
  186. FileSource::FileSource() : compute_frame_(&sample_buffer_), overridden_phase_(),
  187. fade_style_(kWaveBlend), phase_style_(kNone),
  188. normalize_gain_(false), normalize_mult_(false),
  189. random_generator_(-vital::kPi, vital::kPi) {
  190. window_size_ = vital::WaveFrame::kWaveformSize;
  191. random_seed_ = random_generator_.next() * (INT_MAX / vital::kPi);
  192. }
  193. WavetableKeyframe* FileSource::createKeyframe(int position) {
  194. FileSourceKeyframe* keyframe = new FileSourceKeyframe(&sample_buffer_);
  195. interpolate(keyframe, position);
  196. return keyframe;
  197. }
  198. void FileSource::render(vital::WaveFrame* wave_frame, float position) {
  199. if (sample_buffer_.data == nullptr)
  200. wave_frame->clear();
  201. else {
  202. interpolate(&compute_frame_, position);
  203. compute_frame_.setWindowSize(window_size_);
  204. compute_frame_.setFadeStyle(fade_style_);
  205. compute_frame_.setPhaseStyle(phase_style_);
  206. compute_frame_.setInterpolateFromFrame(&interpolate_from_frame_);
  207. compute_frame_.setInterpolateToFrame(&interpolate_to_frame_);
  208. compute_frame_.setOverriddenPhaseBuffer(overridden_phase_);
  209. compute_frame_.render(wave_frame);
  210. wave_frame->setFrequencyRatio(window_size_ / vital::WaveFrame::kWaveformSize);
  211. wave_frame->setSampleRate(sample_buffer_.sample_rate);
  212. if (normalize_mult_)
  213. wave_frame->normalize(normalize_gain_);
  214. wave_frame->toFrequencyDomain();
  215. }
  216. }
  217. WavetableComponentFactory::ComponentType FileSource::getType() {
  218. return WavetableComponentFactory::kFileSource;
  219. }
  220. json FileSource::stateToJson() {
  221. double max_position = 0;
  222. for (int i = 0; i < numFrames(); ++i)
  223. max_position = std::max(max_position, getKeyframe(i)->getStartPosition());
  224. json data = WavetableComponent::stateToJson();
  225. data["normalize_gain"] = normalize_gain_;
  226. data["normalize_mult"] = normalize_mult_;
  227. data["window_size"] = window_size_;
  228. data["fade_style"] = fade_style_;
  229. data["phase_style"] = phase_style_;
  230. data["random_seed"] = random_seed_;
  231. data["audio_sample_rate"] = sample_buffer_.sample_rate;
  232. int save_samples = max_position + 2 * window_size_ + kExtraSaveSamples;
  233. int num_samples = std::min(sample_buffer_.size, save_samples);
  234. String encoded = "";
  235. if (getDataBuffer()) {
  236. std::unique_ptr<int16_t[]> pcm_data = std::make_unique<int16_t[]>(num_samples);
  237. vital::utils::floatToPcmData(pcm_data.get(), getDataBuffer(), num_samples);
  238. encoded = Base64::toBase64(pcm_data.get(), num_samples * sizeof(int16_t));
  239. }
  240. data["audio_file"] = encoded.toStdString();
  241. return data;
  242. }
  243. void FileSource::jsonToState(json data) {
  244. normalize_gain_ = data["normalize_gain"];
  245. if (data.count("normalize_mult"))
  246. normalize_mult_ = data["normalize_mult"];
  247. else
  248. normalize_mult_ = true;
  249. window_size_ = data["window_size"];
  250. fade_style_ = kWaveBlend;
  251. if (data.count("fade_style"))
  252. fade_style_ = data["fade_style"];
  253. phase_style_ = kNone;
  254. if (data.count("phase_style"))
  255. phase_style_ = data["phase_style"];
  256. if (data.count("random_seed"))
  257. random_seed_ = data["random_seed"];
  258. writePhaseOverrideBuffer();
  259. WavetableComponent::jsonToState(data);
  260. int sample_rate = vital::kDefaultSampleRate;
  261. if (data.count("audio_sample_rate"))
  262. sample_rate = data["audio_sample_rate"];
  263. MemoryOutputStream decoded;
  264. std::string audio_data = data["audio_file"];
  265. Base64::convertFromBase64(decoded, audio_data);
  266. int size = static_cast<int>(decoded.getDataSize()) / sizeof(int16_t);
  267. std::unique_ptr<float[]> float_data = std::make_unique<float[]>(size);
  268. vital::utils::pcmToFloatData(float_data.get(), (int16_t*)decoded.getData(), size);
  269. loadBuffer(float_data.get(), size, sample_rate);
  270. }
  271. FileSource::FileSourceKeyframe* FileSource::getKeyframe(int index) {
  272. WavetableKeyframe* wavetable_keyframe = keyframes_[index].get();
  273. return dynamic_cast<FileSource::FileSourceKeyframe*>(wavetable_keyframe);
  274. }
  275. void FileSource::setPhaseStyle(PhaseStyle phase_style) {
  276. if (phase_style_ == phase_style)
  277. return;
  278. phase_style_ = phase_style;
  279. if (phase_style_ == kVocode)
  280. random_seed_++;
  281. writePhaseOverrideBuffer();
  282. }
  283. void FileSource::writePhaseOverrideBuffer() {
  284. if (phase_style_ == kClear) {
  285. for (int i = 0; i < vital::WaveFrame::kWaveformSize / 2; ++i) {
  286. overridden_phase_[2 * i] = -0.5f * vital::kPi;
  287. overridden_phase_[2 * i + 1] = 0.5f * vital::kPi;
  288. }
  289. }
  290. else if (phase_style_ == kVocode) {
  291. random_generator_.seed(random_seed_);
  292. for (int i = 0; i < vital::WaveFrame::kWaveformSize; ++i)
  293. overridden_phase_[i] = random_generator_.next();
  294. }
  295. }
  296. void FileSource::loadBuffer(const float* buffer, int size, int sample_rate) {
  297. sample_buffer_.sample_rate = sample_rate;
  298. sample_buffer_.size = size;
  299. sample_buffer_.data = std::make_unique<float[]>(size + kExtraBufferSamples);
  300. memcpy(sample_buffer_.data.get() + 1, buffer, size * sizeof(float));
  301. sample_buffer_.data[0] = sample_buffer_.data[1];
  302. for (int i = 1; i < kExtraBufferSamples; ++i)
  303. sample_buffer_.data[sample_buffer_.size + i] = sample_buffer_.data[size];
  304. }
  305. void FileSource::detectPitch(int max_period) {
  306. int start = (sample_buffer_.size - kPitchDetectMaxPeriod) / 3;
  307. pitch_detector_.loadSignal(getDataBuffer() + start, kPitchDetectMaxPeriod);
  308. float period = pitch_detector_.matchPeriod(max_period);
  309. setWindowSize(period);
  310. }
  311. void FileSource::detectWaveEditTable() {
  312. static constexpr int kWaveEditFrameLength = 256;
  313. static constexpr int kFrequencyDomainTotals = 8;
  314. static constexpr int kWaveEditNumFrames = 64;
  315. if (sample_buffer_.size != kWaveEditFrameLength * kWaveEditNumFrames)
  316. return;
  317. vital::WaveFrame wave_frame;
  318. const float* buffer = getDataBuffer();
  319. for (int i = 0; i < vital::WaveFrame::kWaveformSize; ++i)
  320. wave_frame.time_domain[i] = buffer[i];
  321. wave_frame.toFrequencyDomain();
  322. int size_mult = vital::WaveFrame::kWaveformSize / kWaveEditFrameLength;
  323. std::unique_ptr<float[]> totals = std::make_unique<float[]>(size_mult);
  324. for (int i = 0; i < size_mult; ++i) {
  325. for (int j = 0; j < kFrequencyDomainTotals; ++j)
  326. totals[i] += std::abs(wave_frame.frequency_domain[i + 1 + j * size_mult]);
  327. }
  328. for (int i = 0; i < size_mult - 1; ++i) {
  329. if (totals[i] > totals[size_mult - 1])
  330. return;
  331. }
  332. setWindowSize(kWaveEditFrameLength);
  333. }