arduino-audio-tools
PureDataStream.h
1 #include "AudioTools/CoreAudio/AudioStreams.h"
2 #include "AudioTools/CoreAudio/Buffers.h"
3 
4 namespace audio_tools {
5 
17 class PureDataStream : public AudioStream {
18  public:
19  PureDataStream(HeavyContextInterface &heavy, int bufferSize = 1024 * 2) {
20  p_heavy = &heavy;
21  buffer_size = bufferSize;
22  }
23 
24  AudioInfo audioInfoOut() override {
25  AudioInfo result(p_heavy->getSampleRate(), p_heavy->getNumOutputChannels(),
26  sample_size * 8);
27  return result;
28  }
29 
30  AudioInfo audioInfo() override {
31  AudioInfo result(p_heavy->getSampleRate(), p_heavy->getNumInputChannels(),
32  sample_size * 8);
33  return result;
34  }
35 
36  void setAudioInfo(AudioInfo newInfo) override {
37  if (audioInfo() != newInfo) {
38  LOGE("The audio format in wrong and can not be changed");
39  }
40  }
41 
42  size_t readBytes(uint8_t *data, size_t len) {
43  int len_max = std::min(len, buffer_read.size());
44  if (buffer_read.isEmpty()) readWrite(len_max);
45  return buffer_read.readArray(data, len_max);
46  }
47 
48  size_t write(const uint8_t *data, size_t len) {
49  int len_max = std::min(len, buffer_write.size());
50  if (!buffer_write.isEmpty()) readWrite(len_max);
51  return buffer_write.writeArray(data, len_max);
52  }
53 
54  bool begin() {
55  int sample_rate = p_heavy->getSampleRate();
56  in_channels = p_heavy->getNumInputChannels();
57  out_channels = p_heavy->getNumOutputChannels();
58  if (out_channels > 0) buffer_read.resize(buffer_size);
59  if (in_channels > 0) buffer_write.resize(buffer_size);
60  if (audioInfo() != audioInfoOut()) {
61  LOGW("rate: %d, channels: in=%d, out=%d", sample_rate, in_channels,
62  out_channels);
63  } else {
64  LOGI("rate: %d, channels: in=%d, out=%d", sample_rate, in_channels,
65  out_channels);
66  }
67  return in_channels > 0 || out_channels > 0;
68  }
69 
70  void flush() { readWrite(buffer_write.available() / sample_size); }
71 
72  void end() {
73  flush();
74  buffer_read.resize(0);
75  buffer_write.resize(0);
76  in.resize(0);
77  out.resize(0);
78  }
79 
80  protected:
81  HeavyContextInterface *p_heavy = nullptr;
82  RingBuffer<uint8_t> buffer_write{0};
83  RingBuffer<uint8_t> buffer_read{0};
84  Vector<float> in{0};
85  Vector<float> out{0};
86  float volume = 1.0f;
87  int buffer_size;
88  const float max_int = 32767.0;
89  const int sample_size = sizeof(int16_t);
90  int in_channels = 0;
91  int out_channels = 0;
92 
93  // returns bytes
94  void readWrite(int bytes) {
95  if (bytes == 0) return;
96  int samples = bytes / sample_size;
97  // size must be multiple of HV_N_SIMD
98  samples = samples / HV_N_SIMD * HV_N_SIMD;
99  int frames = samples / out_channels;
100 
101  if (in.size()<samples) in.resize(samples);
102  if (out.size()<samples) out.resize(samples);
103 
104  // convert int16 to float
105  if (buffer_write.size() > 0) {
106  for (int j = 0; j < samples; j++) {
107  int16_t tmp16 = 0;
108  size_t eff = buffer_write.readArray((uint8_t *)&tmp16, sample_size);
109  assert(eff == sample_size);
110  in[j] = volume * tmp16 / max_int;
111  }
112  }
113 
114  // process data
115  int frames_eff = p_heavy->processInlineInterleaved(in.data(), out.data(), frames);
116  // LOGI("%d -> %d", frames, frames_eff);
117  assert(frames == frames_eff);
118 
119  // convert intput to int16
120  if (buffer_read.size() > 0) {
121  for (int j = 0; j < samples; j++) {
122  int16_t tmp16 = volume * out[j] * max_int;
123  size_t eff = buffer_read.writeArray((uint8_t *)&tmp16, sample_size);
124  assert(eff == sample_size);
125  }
126  }
127  }
128 };
129 
130 } // namespace audio_tools
Base class for all Audio Streams. It support the boolean operator to test if the object is ready with...
Definition: BaseStream.h:109
virtual int readArray(T data[], int len)
reads multiple values
Definition: Buffers.h:41
virtual int writeArray(const T data[], int len)
Fills the buffer data.
Definition: Buffers.h:65
Input and output of Pure Data PD using code generated by the hvcc compiler. The audio format is defin...
Definition: PureDataStream.h:17
void setAudioInfo(AudioInfo newInfo) override
Defines the input AudioInfo.
Definition: PureDataStream.h:36
AudioInfo audioInfoOut() override
provides the actual output AudioInfo: this is usually the same as audioInfo() unless we use a transfo...
Definition: PureDataStream.h:24
AudioInfo audioInfo() override
provides the actual input AudioInfo
Definition: PureDataStream.h:30
virtual int available()
provides the number of entries that are available to read
Definition: Buffers.h:366
virtual size_t size()
Returns the maximum capacity of the buffer.
Definition: Buffers.h:383
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition: AudioConfig.h:823
Basic Audio information which drives e.g. I2S.
Definition: AudioTypes.h:52