Buffer.cpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  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. #include "Buffer.h"
  8. #include <AK/Atomic.h>
  9. #include <AK/Debug.h>
  10. #include <AK/StdLibExtras.h>
  11. #include <AK/String.h>
  12. namespace Audio {
  13. u16 pcm_bits_per_sample(PcmSampleFormat format)
  14. {
  15. switch (format) {
  16. case Uint8:
  17. return 8;
  18. case Int16:
  19. return 16;
  20. case Int24:
  21. return 24;
  22. case Int32:
  23. case Float32:
  24. return 32;
  25. case Float64:
  26. return 64;
  27. default:
  28. VERIFY_NOT_REACHED();
  29. }
  30. }
  31. String sample_format_name(PcmSampleFormat format)
  32. {
  33. bool is_float = format == Float32 || format == Float64;
  34. return String::formatted("PCM {}bit {}", pcm_bits_per_sample(format), is_float ? "Float" : "LE");
  35. }
  36. i32 Buffer::allocate_id()
  37. {
  38. static Atomic<i32> next_id;
  39. return next_id++;
  40. }
  41. template<typename SampleReader>
  42. static void read_samples_from_stream(InputMemoryStream& stream, SampleReader read_sample, Vector<Sample>& samples, int num_channels)
  43. {
  44. double left_channel_sample = 0;
  45. double right_channel_sample = 0;
  46. switch (num_channels) {
  47. case 1:
  48. for (;;) {
  49. left_channel_sample = read_sample(stream);
  50. samples.append(Sample(left_channel_sample));
  51. if (stream.handle_any_error()) {
  52. break;
  53. }
  54. }
  55. break;
  56. case 2:
  57. for (;;) {
  58. left_channel_sample = read_sample(stream);
  59. right_channel_sample = read_sample(stream);
  60. samples.append(Sample(left_channel_sample, right_channel_sample));
  61. if (stream.handle_any_error()) {
  62. break;
  63. }
  64. }
  65. break;
  66. default:
  67. VERIFY_NOT_REACHED();
  68. }
  69. }
  70. static double read_float_sample_64(InputMemoryStream& stream)
  71. {
  72. LittleEndian<double> sample;
  73. stream >> sample;
  74. return double(sample);
  75. }
  76. static double read_float_sample_32(InputMemoryStream& stream)
  77. {
  78. LittleEndian<float> sample;
  79. stream >> sample;
  80. return double(sample);
  81. }
  82. static double read_norm_sample_24(InputMemoryStream& stream)
  83. {
  84. u8 byte = 0;
  85. stream >> byte;
  86. u32 sample1 = byte;
  87. stream >> byte;
  88. u32 sample2 = byte;
  89. stream >> byte;
  90. u32 sample3 = byte;
  91. i32 value = 0;
  92. value = sample1 << 8;
  93. value |= (sample2 << 16);
  94. value |= (sample3 << 24);
  95. return double(value) / NumericLimits<i32>::max();
  96. }
  97. static double read_norm_sample_16(InputMemoryStream& stream)
  98. {
  99. LittleEndian<i16> sample;
  100. stream >> sample;
  101. return double(sample) / NumericLimits<i16>::max();
  102. }
  103. static double read_norm_sample_8(InputMemoryStream& stream)
  104. {
  105. u8 sample = 0;
  106. stream >> sample;
  107. return double(sample) / NumericLimits<u8>::max();
  108. }
  109. ErrorOr<NonnullRefPtr<Buffer>> Buffer::from_pcm_data(ReadonlyBytes data, int num_channels, PcmSampleFormat sample_format)
  110. {
  111. InputMemoryStream stream { data };
  112. return from_pcm_stream(stream, num_channels, sample_format, data.size() / (pcm_bits_per_sample(sample_format) / 8));
  113. }
  114. ErrorOr<NonnullRefPtr<Buffer>> Buffer::from_pcm_stream(InputMemoryStream& stream, int num_channels, PcmSampleFormat sample_format, int num_samples)
  115. {
  116. Vector<Sample> fdata;
  117. fdata.ensure_capacity(num_samples);
  118. switch (sample_format) {
  119. case PcmSampleFormat::Uint8:
  120. read_samples_from_stream(stream, read_norm_sample_8, fdata, num_channels);
  121. break;
  122. case PcmSampleFormat::Int16:
  123. read_samples_from_stream(stream, read_norm_sample_16, fdata, num_channels);
  124. break;
  125. case PcmSampleFormat::Int24:
  126. read_samples_from_stream(stream, read_norm_sample_24, fdata, num_channels);
  127. break;
  128. case PcmSampleFormat::Float32:
  129. read_samples_from_stream(stream, read_float_sample_32, fdata, num_channels);
  130. break;
  131. case PcmSampleFormat::Float64:
  132. read_samples_from_stream(stream, read_float_sample_64, fdata, num_channels);
  133. break;
  134. default:
  135. VERIFY_NOT_REACHED();
  136. }
  137. // We should handle this in a better way above, but for now --
  138. // just make sure we're good. Worst case we just write some 0s where they
  139. // don't belong.
  140. VERIFY(!stream.handle_any_error());
  141. return Buffer::create_with_samples(move(fdata));
  142. }
  143. template<typename SampleType>
  144. ResampleHelper<SampleType>::ResampleHelper(u32 source, u32 target)
  145. : m_source(source)
  146. , m_target(target)
  147. {
  148. VERIFY(source > 0);
  149. VERIFY(target > 0);
  150. }
  151. template ResampleHelper<i32>::ResampleHelper(u32, u32);
  152. template ResampleHelper<double>::ResampleHelper(u32, u32);
  153. template<typename SampleType>
  154. Vector<SampleType> ResampleHelper<SampleType>::resample(Vector<SampleType> to_resample)
  155. {
  156. Vector<SampleType> resampled;
  157. resampled.ensure_capacity(to_resample.size() * ceil_div(m_source, m_target));
  158. for (auto sample : to_resample) {
  159. process_sample(sample, sample);
  160. while (read_sample(sample, sample))
  161. resampled.unchecked_append(sample);
  162. }
  163. return resampled;
  164. }
  165. template Vector<i32> ResampleHelper<i32>::resample(Vector<i32>);
  166. template Vector<double> ResampleHelper<double>::resample(Vector<double>);
  167. ErrorOr<NonnullRefPtr<Buffer>> resample_buffer(ResampleHelper<double>& resampler, Buffer const& to_resample)
  168. {
  169. Vector<Sample> resampled;
  170. resampled.ensure_capacity(to_resample.sample_count() * ceil_div(resampler.source(), resampler.target()));
  171. for (size_t i = 0; i < static_cast<size_t>(to_resample.sample_count()); ++i) {
  172. auto sample = to_resample.samples()[i];
  173. resampler.process_sample(sample.left, sample.right);
  174. while (resampler.read_sample(sample.left, sample.right))
  175. resampled.append(sample);
  176. }
  177. return Buffer::create_with_samples(move(resampled));
  178. }
  179. template<typename SampleType>
  180. void ResampleHelper<SampleType>::process_sample(SampleType sample_l, SampleType sample_r)
  181. {
  182. m_last_sample_l = sample_l;
  183. m_last_sample_r = sample_r;
  184. m_current_ratio += m_target;
  185. }
  186. template void ResampleHelper<i32>::process_sample(i32, i32);
  187. template void ResampleHelper<double>::process_sample(double, double);
  188. template<typename SampleType>
  189. bool ResampleHelper<SampleType>::read_sample(SampleType& next_l, SampleType& next_r)
  190. {
  191. if (m_current_ratio >= m_source) {
  192. m_current_ratio -= m_source;
  193. next_l = m_last_sample_l;
  194. next_r = m_last_sample_r;
  195. return true;
  196. }
  197. return false;
  198. }
  199. template bool ResampleHelper<i32>::read_sample(i32&, i32&);
  200. template bool ResampleHelper<double>::read_sample(double&, double&);
  201. template<typename SampleType>
  202. void ResampleHelper<SampleType>::reset()
  203. {
  204. m_current_ratio = 0;
  205. m_last_sample_l = {};
  206. m_last_sample_r = {};
  207. }
  208. template void ResampleHelper<i32>::reset();
  209. template void ResampleHelper<double>::reset();
  210. }