Buffer.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /*
  2. * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
  3. * Copyright (c) 2021, kleines Filmröllchen <malu.bertsch@gmail.com>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #pragma once
  8. #include <AK/ByteBuffer.h>
  9. #include <AK/MemoryStream.h>
  10. #include <AK/String.h>
  11. #include <AK/Types.h>
  12. #include <AK/Vector.h>
  13. #include <LibCore/AnonymousBuffer.h>
  14. #include <string.h>
  15. namespace Audio {
  16. // A single sample in an audio buffer.
  17. // Values are floating point, and should range from -1.0 to +1.0
  18. struct Frame {
  19. Frame()
  20. : left(0)
  21. , right(0)
  22. {
  23. }
  24. // For mono
  25. Frame(double left)
  26. : left(left)
  27. , right(left)
  28. {
  29. }
  30. // For stereo
  31. Frame(double left, double right)
  32. : left(left)
  33. , right(right)
  34. {
  35. }
  36. void clip()
  37. {
  38. if (left > 1)
  39. left = 1;
  40. else if (left < -1)
  41. left = -1;
  42. if (right > 1)
  43. right = 1;
  44. else if (right < -1)
  45. right = -1;
  46. }
  47. void scale(int percent)
  48. {
  49. double pct = (double)percent / 100.0;
  50. left *= pct;
  51. right *= pct;
  52. }
  53. Frame& operator+=(const Frame& other)
  54. {
  55. left += other.left;
  56. right += other.right;
  57. return *this;
  58. }
  59. double left;
  60. double right;
  61. };
  62. // Supported PCM sample formats.
  63. enum PcmSampleFormat : u8 {
  64. Uint8,
  65. Int16,
  66. Int24,
  67. Int32,
  68. Float32,
  69. Float64,
  70. };
  71. // Most of the read code only cares about how many bits to read or write
  72. u16 pcm_bits_per_sample(PcmSampleFormat format);
  73. String sample_format_name(PcmSampleFormat format);
  74. // Small helper to resample from one playback rate to another
  75. // This isn't really "smart", in that we just insert (or drop) samples.
  76. // Should do better...
  77. template<typename SampleType>
  78. class ResampleHelper {
  79. public:
  80. ResampleHelper(double source, double target);
  81. // To be used as follows:
  82. // while the resampler doesn't need a new sample, read_sample(current) and store the resulting samples.
  83. // as long as the resampler needs a new sample, process_sample(current)
  84. // Stores a new sample
  85. void process_sample(SampleType sample_l, SampleType sample_r);
  86. // Assigns the given sample to its correct value and returns false if there is a new sample required
  87. bool read_sample(SampleType& next_l, SampleType& next_r);
  88. Vector<SampleType> resample(Vector<SampleType> to_resample);
  89. private:
  90. const double m_ratio;
  91. double m_current_ratio { 0 };
  92. SampleType m_last_sample_l;
  93. SampleType m_last_sample_r;
  94. };
  95. // A buffer of audio samples, normalized to 44100hz.
  96. class Buffer : public RefCounted<Buffer> {
  97. public:
  98. static RefPtr<Buffer> from_pcm_data(ReadonlyBytes data, ResampleHelper<double>& resampler, int num_channels, PcmSampleFormat sample_format);
  99. static RefPtr<Buffer> from_pcm_stream(InputMemoryStream& stream, ResampleHelper<double>& resampler, int num_channels, PcmSampleFormat sample_format, int num_samples);
  100. static NonnullRefPtr<Buffer> create_with_samples(Vector<Frame>&& samples)
  101. {
  102. return adopt_ref(*new Buffer(move(samples)));
  103. }
  104. static NonnullRefPtr<Buffer> create_with_anonymous_buffer(Core::AnonymousBuffer buffer, i32 buffer_id, int sample_count)
  105. {
  106. return adopt_ref(*new Buffer(move(buffer), buffer_id, sample_count));
  107. }
  108. const Frame* samples() const { return (const Frame*)data(); }
  109. int sample_count() const { return m_sample_count; }
  110. const void* data() const { return m_buffer.data<void>(); }
  111. int size_in_bytes() const { return m_sample_count * (int)sizeof(Frame); }
  112. int id() const { return m_id; }
  113. const Core::AnonymousBuffer& anonymous_buffer() const { return m_buffer; }
  114. private:
  115. explicit Buffer(const Vector<Frame> samples)
  116. : m_buffer(Core::AnonymousBuffer::create_with_size(samples.size() * sizeof(Frame)))
  117. , m_id(allocate_id())
  118. , m_sample_count(samples.size())
  119. {
  120. memcpy(m_buffer.data<void>(), samples.data(), samples.size() * sizeof(Frame));
  121. }
  122. explicit Buffer(Core::AnonymousBuffer buffer, i32 buffer_id, int sample_count)
  123. : m_buffer(move(buffer))
  124. , m_id(buffer_id)
  125. , m_sample_count(sample_count)
  126. {
  127. }
  128. static i32 allocate_id();
  129. Core::AnonymousBuffer m_buffer;
  130. const i32 m_id;
  131. const int m_sample_count;
  132. };
  133. }