2
0

BellDSP.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. #include "BellDSP.h"
  2. #include <type_traits> // for remove_extent_t
  3. #include <utility> // for move
  4. #include "AudioPipeline.h" // for CentralAudioBuffer
  5. #include "CentralAudioBuffer.h" // for CentralAudioBuffer
  6. using namespace bell;
  7. BellDSP::FadeEffect::FadeEffect(size_t duration, bool isFadeIn,
  8. std::function<void()> onFinish) {
  9. this->duration = duration;
  10. this->onFinish = onFinish;
  11. this->isFadeIn = isFadeIn;
  12. }
  13. void BellDSP::FadeEffect::apply(float* audioData, size_t samples,
  14. size_t relativePosition) {
  15. float effect = (this->duration - relativePosition) / (float)this->duration;
  16. if (isFadeIn) {
  17. effect = relativePosition / (float)this->duration;
  18. }
  19. for (int x = 0; x <= samples; x++) {
  20. audioData[x] *= effect;
  21. }
  22. if (relativePosition + samples > this->duration && onFinish != nullptr) {
  23. onFinish();
  24. }
  25. }
  26. BellDSP::BellDSP(std::shared_ptr<CentralAudioBuffer> buffer) {
  27. this->buffer = buffer;
  28. };
  29. void BellDSP::applyPipeline(std::shared_ptr<AudioPipeline> pipeline) {
  30. std::scoped_lock lock(accessMutex);
  31. activePipeline = pipeline;
  32. }
  33. void BellDSP::queryInstantEffect(std::unique_ptr<AudioEffect> instantEffect) {
  34. this->instantEffect = std::move(instantEffect);
  35. samplesSinceInstantQueued = 0;
  36. }
  37. size_t BellDSP::process(uint8_t* data, size_t bytes, int channels,
  38. uint32_t sampleRate, BitWidth bitWidth) {
  39. if (bytes > 1024 * 2 * channels) {
  40. return 0;
  41. }
  42. size_t bytesPerSample = channels * 2;
  43. size_t samplesLeftInBuffer = buffer->audioBuffer->size() / bytesPerSample;
  44. // Create a StreamInfo object to pass to the pipeline
  45. auto streamInfo = std::make_unique<StreamInfo>();
  46. streamInfo->numChannels = channels;
  47. streamInfo->sampleRate = static_cast<bell::SampleRate>(sampleRate);
  48. streamInfo->bitwidth = bitWidth;
  49. streamInfo->numSamples = bytes / channels / 2;
  50. std::scoped_lock lock(accessMutex);
  51. int16_t* data16Bit = (int16_t*)data;
  52. int length16 = bytes / 4;
  53. for (size_t i = 0; i < length16; i++) {
  54. dataLeft[i] = (data16Bit[i * 2] / (float)MAX_INT16); // Normalize left
  55. dataRight[i] =
  56. (data16Bit[i * 2 + 1] / (float)MAX_INT16); // Normalize right
  57. }
  58. float* sampleData[] = {&dataLeft[0], &dataRight[0]};
  59. streamInfo->data = sampleData;
  60. if (activePipeline) {
  61. streamInfo = activePipeline->process(std::move(streamInfo));
  62. }
  63. if (this->instantEffect != nullptr) {
  64. this->instantEffect->apply(dataLeft.data(), length16,
  65. samplesSinceInstantQueued);
  66. if (streamInfo->numSamples > 1) {
  67. this->instantEffect->apply(dataRight.data(), length16,
  68. samplesSinceInstantQueued);
  69. }
  70. samplesSinceInstantQueued += length16;
  71. if (this->instantEffect->duration <= samplesSinceInstantQueued) {
  72. this->instantEffect = nullptr;
  73. }
  74. }
  75. for (size_t i = 0; i < length16; i++) {
  76. if (dataLeft[i] > 1.0f) {
  77. dataLeft[i] = 1.0f;
  78. }
  79. // Data has been downmixed to mono
  80. if (streamInfo->numChannels == 1) {
  81. data16Bit[i] = dataLeft[i] * MAX_INT16; // Denormalize left
  82. } else {
  83. data16Bit[i * 2] = dataLeft[i] * MAX_INT16; // Denormalize left
  84. data16Bit[i * 2 + 1] = dataRight[i] * MAX_INT16; // Denormalize right
  85. }
  86. }
  87. if (streamInfo->numChannels == 1) {
  88. return bytes / 2;
  89. }
  90. return bytes;
  91. }
  92. std::shared_ptr<AudioPipeline> BellDSP::getActivePipeline() {
  93. return activePipeline;
  94. }