arduino-audio-tools
LoRaStream.h
1 #pragma once
2 
3 #include "AudioTools/CoreAudio/Buffers.h"
4 #include "LoRa.h" // https://github.com/sandeepmistry/arduino-LoRa
5 
6 // define the default pins used by the transceiver module
7 #define rst 12
8 #define dio0 14
9 
10 namespace audio_tools {
11 
30 struct LoRaConfig : public AudioInfo {
31  LoRaConfig() {
32  sample_rate = 0;
33  channels = 0;
34  bits_per_sample = 0;
35  }
36  int sync_word = 0xF3; // 0x0-0xFF
37  int32_t spi_speed = 8000000;
38  int max_size = 200; // max 256 bytes
39  int frequency = 868E6; // (Asio:433E6, EU:868E6, US: 915E6)
40  int tx_power = 20; // 2-20;
41  int spreading_factor = 6; // 6-12 (6 fastest)
42  // 7.8E3, 10.4E3, 15.6E3, 20.8E3, 31.25E3, 41.7E3, 62.5E3, 125E3, 250E3, and
43  // 500E3 (fastest)
44  int signal_bandwidth = 500E3;
45  int pin_ss = SS;
46  int pin_rst = rst;
47  int pin_dio0 = dio0;
48  int max_begin_retry = 10;
49 };
50 
57 class LoRaStream : public AudioStream {
58  public:
59  LoRaConfig defaultConfig() {
60  LoRaConfig rc;
61  return rc;
62  }
63 
64  void setAudioInfo(AudioInfo info) {
65  cfg.sample_rate = info.sample_rate;
66  cfg.channels = info.channels;
69  }
70 
71  bool begin(LoRaConfig config) {
72  cfg = config;
74  return begin();
75  }
76 
77  bool begin() {
78  TRACEI();
79  is_audio_info_sent = false;
80  buffer.resize(cfg.max_size);
81  bool rc;
82  int count = 0;
83  LOGI("LoRa begin...");
84  LoRa.setPins(cfg.pin_ss, cfg.pin_rst, cfg.pin_dio0);
85  do {
86  rc = LoRa.begin(cfg.frequency);
87  if (++count > cfg.max_begin_retry) return false;
88  if (!rc){
89  LOGI("LoRa begin failed");
90  delay(800);
91  }
92  } while(!rc);
93  LoRa.setSignalBandwidth(cfg.signal_bandwidth);
94  LoRa.setSpreadingFactor(cfg.spreading_factor);
95  LoRa.setTxPower(cfg.tx_power);
96  LoRa.setSPIFrequency(cfg.spi_speed);
97  LoRa.setSyncWord(cfg.sync_word);
98  if (rc) LOGI("LoRa begin success");
99  return rc;
100  }
101 
102  void end() {
103  TRACEI();
104  LoRa.end();
105  }
106 
107  size_t readBytes(uint8_t* data, size_t len) {
108  LOGI("LoRaStream::readBytes: %d", len);
109  size_t packetSize = LoRa.parsePacket();
110  if (!cfg && packetSize == sizeof(AudioInfo)) {
111  readAudioInfo();
112  packetSize = LoRa.parsePacket();
113  }
114  int toRead = min(len, packetSize);
115  int read = LoRa.readBytes(data, toRead);
116  return read;
117  }
118 
119  int available() { return cfg.max_size; }
120 
121  int availableForWrite() { return cfg.max_size; }
122 
123  size_t write(const uint8_t* data, size_t len) {
124  LOGI("LoRaStream::write: %d", len);
125 
126  if (cfg && !is_audio_info_sent) {
127  writeAudioInfo();
128  is_audio_info_sent = true;
129  }
130 
131  for (int j = 0; j < len; j++) {
132  buffer.write(data[j]);
133  if (buffer.isFull()) {
134  LoRa.beginPacket();
135  LoRa.write(buffer.data(), buffer.available());
136  LoRa.endPacket();
137  buffer.clear();
138  }
139  }
140  return len;
141  }
142 
143  protected:
144  LoRaConfig cfg;
145  SingleBuffer<uint8_t> buffer;
146  bool is_audio_info_sent = false;
147 
148  void readAudioInfo() {
149  TRACED();
150  AudioInfo tmp;
151  int read = LoRa.readBytes((uint8_t*)&tmp, sizeof(AudioInfo));
152  if (tmp) setAudioInfo(tmp);
153  }
154 
155  void writeAudioInfo() {
156  TRACED();
157  LoRa.beginPacket();
158  AudioInfo ai = audioInfo();
159  LoRa.write((uint8_t*)&ai, sizeof(ai));
160  LoRa.endPacket();
161  }
162 };
163 
164 } // 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:113
virtual void setAudioInfo(AudioInfo newInfo) override
Defines the input AudioInfo.
Definition: BaseStream.h:121
virtual AudioInfo audioInfo() override
provides the actual input AudioInfo
Definition: BaseStream.h:144
void clear()
same as reset
Definition: Buffers.h:134
LoRa: Sending and Receiving Audio.
Definition: LoRaStream.h:57
void setAudioInfo(AudioInfo info)
Defines the input AudioInfo.
Definition: LoRaStream.h:64
T * data()
Provides address of actual data.
Definition: Buffers.h:252
bool write(T sample) override
write add an entry to the buffer
Definition: Buffers.h:194
int available() override
provides the number of entries that are available to read
Definition: Buffers.h:219
bool isFull() override
checks if the buffer is full
Definition: Buffers.h:226
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition: AudioConfig.h:872
Basic Audio information which drives e.g. I2S.
Definition: AudioTypes.h:52
sample_rate_t sample_rate
Sample Rate: e.g 44100.
Definition: AudioTypes.h:55
uint16_t channels
Number of channels: 2=stereo, 1=mono.
Definition: AudioTypes.h:57
uint8_t bits_per_sample
Number of bits per sample (int16_t = 16 bits)
Definition: AudioTypes.h:59
LoRa Audio Configuration with default values maximised for speed using the LoRa library from sandeepm...
Definition: LoRaStream.h:30