Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
pschatzmann committed Nov 6, 2023
2 parents a5f337c + 520f391 commit db98bdb
Show file tree
Hide file tree
Showing 11 changed files with 296 additions and 113 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* @file communications-ble-client-send.ino
* @author Phil Schatzmann
* @brief Sending audio via BLE: the client acts as audio source
* @version 0.1
* @date 2022-11-04
*
* @copyright Copyright (c) 2022
*/


#include "AudioTools.h"
#include "AudioCodecs/CodecADPCM.h" // https://github.com/pschatzmann/adpcm
#include "Sandbox/BLE/AudioBLE.h"

AudioInfo info(16000, 1, 16);
SineWaveGenerator<int16_t> sineWave( 32000); // subclass of SoundGenerator with max amplitude of 32000
GeneratedSoundStream<int16_t> sound( sineWave); // Stream generated from sine wave
Throttle throttle(sound);
AudioBLEClient ble;
ADPCMEncoder adpcm(AV_CODEC_ID_ADPCM_IMA_WAV);
EncodedAudioStream encoder(&ble, &adpcm);
StreamCopy copier(encoder, throttle);

void setup() {
Serial.begin(115200);
AudioLogger::instance().begin(Serial, AudioLogger::Info);

sineWave.begin(info, N_B4);
throttle.begin(info);
encoder.begin(info);
ble.begin("ble-send", 60*10);

Serial.println("started...");
}

void loop() {
copier.copy();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* @file communications-ble-server-receive.ino
* @author Phil Schatzmann
* @brief Receiving audio via BLE: the server acts as audio sink
* @version 0.1
* @date 2022-11-04
*
* @copyright Copyright (c) 2022
*/

#include "AudioTools.h"
#include "AudioCodecs/CodecADPCM.h" // https://github.com/pschatzmann/adpcm
#include "Sandbox/BLE/AudioBLE.h"
//#include "AudioLibs/AudioKit.h"

AudioInfo info(16000, 1, 16);
ADPCMDecoder adpcm(AV_CODEC_ID_ADPCM_IMA_WAV);
I2SStream i2s; // or AudioKitStream ...
EncodedAudioStream decoder(&i2s, &adpcm);
AudioBLEServer ble;
StreamCopy copier(decoder, ble);

void setup() {
Serial.begin(115200);
AudioLogger::instance().begin(Serial, AudioLogger::Warning);

decoder.begin(info);

auto cfg = i2s.defaultConfig();
cfg.copyFrom(info);
i2s.begin(cfg);

ble.begin("ble-receive");
}

void loop() {
copier.copy();
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/**
* @file example-serial-receive.ino
* @file communications-ble-client-receive.ino
* @author Phil Schatzmann
* @brief Receiving audio via BLE and writing to I2S
* @brief Receiving audio via BLE: The client acts as audio sink and is writing to I2S
* @version 0.1
* @date 2022-03-09
* @date 2022-11-04
*
* @copyright Copyright (c) 2022
* @copyright Copyright (c) 2023
*/


Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/**
* @file communications-ble-send.ino
* @file communications-ble-server-send.ino
* @author Phil Schatzmann
* @brief Sending audio via BLE
* @brief Sending audio via BLE: The server acts as audio source
* @version 0.1
* @date 2022-03-09
* @date 2022-11-04
*
* @copyright Copyright (c) 2022
* @copyright Copyright (c) 2023
*/

#include "AudioTools.h"
Expand Down
20 changes: 20 additions & 0 deletions examples/tests/performance/throttle/throttle.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include "AudioTools.h"

AudioInfo info(44100, 2, 16);
SilenceGenerator<int16_t> silence;
GeneratedSoundStream<int16_t> sound(silence);
Throttle throttle(sound);
MeasuringStream out(200, &Serial);
StreamCopy copier(out, throttle);

void setup() {
Serial.begin(115200);
AudioLogger::instance().begin(Serial, AudioLogger::Warning);

out.begin(info);
sound.begin(info);
throttle.begin(info);

}

void loop() { copier.copy(); }
9 changes: 7 additions & 2 deletions src/AudioCodecs/AudioEncoded.h
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ class EncodedAudioOutput : public AudioStream {
return 0;
}

if(availableForWrite()==0){
if(check_available_for_write && availableForWrite()==0){
return 0;
}

Expand All @@ -400,14 +400,19 @@ class EncodedAudioOutput : public AudioStream {
void setLogLevel(AudioLogger::LogLevel level){
custom_log_level.set(level);
}
/// Is Available for Write check activated ?
bool isCheckAvailableForWrite() {
return check_available_for_write;
}

protected:
//AudioInfo info;
AudioDecoder *decoder_ptr = CodecNOP::instance(); // decoder
AudioEncoder *encoder_ptr = CodecNOP::instance(); // decoder
AudioWriter *writer_ptr = nullptr;
Print *ptr_out = nullptr;
bool active;
bool active = false;
bool check_available_for_write = false;
CustomLogLevel custom_log_level;
};

Expand Down
88 changes: 0 additions & 88 deletions src/AudioTools/AudioOutput.h
Original file line number Diff line number Diff line change
Expand Up @@ -731,92 +731,4 @@ class ChannelSplitOutput : public AudioOutput {
Vector<ChannelSelectionOutputDef> out_chanels;
};


/**
* @brief Configure Throttle setting
* @author Phil Schatzmann
* @copyright GPLv3
*/
struct ThrottleConfig : public AudioInfo {
ThrottleConfig() {
sample_rate = 44100;
bits_per_sample = 16;
channels = 2;
}
int correction_us = 0;
};


/**
* @brief Throttle the sending of the audio data to limit it to the indicated
* sample rate.
* @author Phil Schatzmann
* @copyright GPLv3
*/
class Throttle : public AudioOutput {
public:
Throttle() = default;
Throttle(Print &out) { p_out = &out; }

ThrottleConfig defaultConfig() {
ThrottleConfig c;
return c;
}

bool begin(ThrottleConfig info) {
AudioOutput::begin(info);
this->info = info;
return begin();
}

bool begin(){
info.copyFrom(cfg);
bytesPerSample = info.bits_per_sample / 8 * info.channels;
startDelay();
return true;
}

// (re)starts the timing
void startDelay() {
start_time = micros();
sum_samples = 0;
}

int availableForWrite() {
if (p_out){
return p_out->availableForWrite();
}
return DEFAULT_BUFFER_SIZE;
}

size_t write(const uint8_t* data, size_t len){
size_t result = p_out->write(data, len);
delayBytes(len);
return result;
}

// delay
void delayBytes(size_t bytes) { delaySamples(bytes / bytesPerSample); }

// delay
void delaySamples(size_t samples) {
sum_samples += samples;
int64_t durationUsEff = micros() - start_time;
int64_t durationUsToBe = (sum_samples * 1000000) / info.sample_rate;
int64_t waitUs = durationUsToBe - durationUsEff + info.correction_us;
LOGI("wait: %d", (int)waitUs);
if (waitUs > 0) {
delayMicroseconds(waitUs);
}
}

protected:
uint32_t start_time = 0;
uint32_t sum_samples = 0;
ThrottleConfig info;
int bytesPerSample = 0;
Print *p_out = nullptr;
};


} // namespace audio_tools
4 changes: 1 addition & 3 deletions src/AudioTools/AudioPlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,7 @@ namespace audio_tools {
autonext = p_source->isAutoNext();

// initial audio info for fade from output when not defined yet
if (fade.audioInfo().channels==0){
setupFade();
}
setupFade();

// start dependent objects
p_out_decoding->begin();
Expand Down
Loading

0 comments on commit db98bdb

Please sign in to comment.