Skip to content

Commit e6dd304

Browse files
committed
ContainerBinary DRAFT
1 parent 5fe4ead commit e6dd304

File tree

6 files changed

+269
-167
lines changed

6 files changed

+269
-167
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
cmake_minimum_required(VERSION 3.20)
2+
3+
# set the project name
4+
project(container-binary)
5+
set (CMAKE_CXX_STANDARD 11)
6+
set (DCMAKE_CXX_FLAGS "-Werror")
7+
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
8+
set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address")
9+
set (CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address")
10+
endif()
11+
include(FetchContent)
12+
13+
# Build with arduino-audio-tools
14+
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
15+
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../../.. ${CMAKE_CURRENT_BINARY_DIR}/arduino-audio-tools )
16+
endif()
17+
18+
19+
# build sketch as executable
20+
add_executable (container-binary container-binary.cpp)
21+
22+
# set preprocessor defines
23+
target_compile_definitions(container-binary PUBLIC -DEXIT_ON_STOP -DIS_MIN_DESKTOP)
24+
25+
# OS/X might need this setting for core audio
26+
#target_compile_definitions(portaudio PUBLIC -DPA_USE_COREAUDIO=1)
27+
28+
# specify libraries
29+
target_link_libraries(container-binary arduino-audio-tools)
30+
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/**
2+
* @file communication-container-binary.ino
3+
* @author Phil Schatzmann
4+
* @brief generate sine wave -> encoder -> decoder -> audiokit (i2s)
5+
* @version 0.1
6+
* @date 2022-04-30
7+
*
8+
* @copyright Copyright (c) 2022
9+
*
10+
*/
11+
#include "AudioTools.h"
12+
#include "AudioCodecs/ContainerBinary.h"
13+
14+
AudioInfo info(8000,1,16);
15+
SineWaveGenerator<int16_t> sineWave( 32000); // subclass of SoundGenerator with max amplitude of 32000
16+
GeneratedSoundStream<int16_t> sound( sineWave); // Stream generated from sine wave
17+
CsvStream<int16_t> out(Serial);
18+
EncodedAudioStream decoder(&out,new BinaryContainerDecoder()); // encode and write
19+
EncodedAudioStream encoder(&out,new BinaryContainerEncoder()); // encode and write
20+
StreamCopy copier(encoder, sound);
21+
22+
void setup() {
23+
AudioLogger::instance().begin(Serial, AudioLogger::Warning);
24+
25+
// start
26+
Serial.println("starting...");
27+
auto cfgi = out.defaultConfig(TX_MODE);
28+
cfgi.copyFrom(info);
29+
out.begin(cfgi);
30+
31+
// Setup sine wave
32+
sineWave.begin(info, N_B4);
33+
34+
// start decoder
35+
decoder.begin(info);
36+
37+
// start encoder
38+
encoder.begin(info);
39+
40+
Serial.println("Test started...");
41+
}
42+
43+
44+
void loop() {
45+
copier.copy();
46+
}

src/AudioCodecs/AudioEncoded.h

Lines changed: 100 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,24 @@ class EncodedAudioPrint : public AudioStream {
257257
active = false;
258258
}
259259

260+
EncodedAudioPrint(AudioPrint *outputStream, AudioEncoder *encoder) {
261+
TRACED();
262+
ptr_out = outputStream;
263+
encoder_ptr = encoder;
264+
encoder_ptr->setOutputStream(*outputStream);
265+
writer_ptr = encoder_ptr;
266+
active = false;
267+
}
268+
269+
EncodedAudioPrint(AudioStream *outputStream, AudioEncoder *encoder) {
270+
TRACED();
271+
ptr_out = outputStream;
272+
encoder_ptr = encoder;
273+
encoder_ptr->setOutputStream(*outputStream);
274+
writer_ptr = encoder_ptr;
275+
active = false;
276+
}
277+
260278
/**
261279
* @brief Construct a new Encoded Audio Stream object - the Output and
262280
* Encoder/Decoder needs to be defined with the corresponding setter methods.
@@ -282,9 +300,12 @@ class EncodedAudioPrint : public AudioStream {
282300

283301
virtual void setAudioInfo(AudioInfo info) override {
284302
TRACED();
285-
AudioStream::setAudioInfo(info);
286-
decoder_ptr->setAudioInfo(info);
287-
encoder_ptr->setAudioInfo(info);
303+
if (this->info != info) {
304+
this->info = info;
305+
AudioStream::setAudioInfo(info);
306+
decoder_ptr->setAudioInfo(info);
307+
encoder_ptr->setAudioInfo(info);
308+
}
288309
}
289310

290311
/// Defines the output
@@ -294,6 +315,9 @@ class EncodedAudioPrint : public AudioStream {
294315
void setStream(Print *outputStream) { setOutput(outputStream); }
295316

296317
void setEncoder(AudioEncoder *encoder) {
318+
if (encoder == nullptr) {
319+
encoder = CodecNOP::instance();
320+
}
297321
encoder_ptr = encoder;
298322
writer_ptr = encoder;
299323
if (ptr_out != nullptr) {
@@ -302,6 +326,9 @@ class EncodedAudioPrint : public AudioStream {
302326
}
303327

304328
void setDecoder(AudioDecoder *decoder) {
329+
if (decoder == nullptr) {
330+
decoder = CodecNOP::instance();
331+
}
305332
decoder_ptr = decoder;
306333
writer_ptr = decoder;
307334
if (ptr_out != nullptr) {
@@ -312,13 +339,16 @@ class EncodedAudioPrint : public AudioStream {
312339
/// Starts the processing - sets the status to active
313340
bool begin() override {
314341
TRACED();
315-
const CodecNOP *nop = CodecNOP::instance();
316-
if (decoder_ptr != nop || encoder_ptr != nop) {
317-
decoder_ptr->begin();
318-
encoder_ptr->begin();
319-
active = true;
320-
} else {
321-
LOGW("no decoder or encoder defined");
342+
343+
if (!active) {
344+
const CodecNOP *nop = CodecNOP::instance();
345+
if (decoder_ptr != nop || encoder_ptr != nop) {
346+
active = true;
347+
decoder_ptr->begin();
348+
encoder_ptr->begin();
349+
} else {
350+
LOGW("no decoder or encoder defined");
351+
}
322352
}
323353
return active;
324354
}
@@ -376,6 +406,7 @@ class EncodedAudioPrint : public AudioStream {
376406
AudioEncoder &encoder() { return *encoder_ptr; }
377407

378408
protected:
409+
AudioInfo info;
379410
AudioDecoder *decoder_ptr = CodecNOP::instance(); // decoder
380411
AudioEncoder *encoder_ptr = CodecNOP::instance(); // decoder
381412
AudioWriter *writer_ptr = nullptr;
@@ -561,129 +592,95 @@ class EncodedAudioStream : public EncodedAudioPrint {
561592
};
562593

563594
/**
564-
* @brief ContainerTarget: forwards requests to both the output and the
565-
* encoder/decoder
595+
* @brief Facade class which lets an AudioWriter behave like a Print
596+
* @author Phil Schatzmann
597+
* @copyright GPLv3
566598
*
567599
*/
568-
class ContainerTarget {
569-
public:
570-
virtual bool begin();
571-
virtual void end();
572-
virtual void setAudioInfo(AudioInfo info);
573-
virtual size_t write(uint8_t *data, size_t size);
574-
};
575600

576-
class ContainerTargetPrint : public ContainerTarget {
601+
class AudioWriterToPrint : public AudioPrint {
577602
public:
578-
ContainerTargetPrint(Print &print, AudioWriter *writer) {
579-
p_print = &print;
580-
p_writer = writer;
581-
}
582-
virtual bool begin() {
583-
if (p_writer) {
584-
p_writer->begin();
585-
p_writer->setOutputStream(*p_print);
586-
}
587-
return true;
588-
}
589-
virtual void end() {
590-
if (p_writer) p_writer->end();
591-
}
592-
virtual void setAudioInfo(AudioInfo info) {
593-
if (p_writer) p_writer->setAudioInfo(info);
594-
}
595-
virtual size_t write(uint8_t *data, size_t size) {
596-
TRACED();
597-
return p_writer ? p_writer->write(data, size) : p_print->write(data, size);
598-
}
603+
void setWriter(AudioWriter *writer) { p_writer = writer; }
604+
size_t write(const uint8_t *in_ptr, size_t in_size) {
605+
return p_writer->write(in_ptr, in_size);
606+
};
599607

600608
protected:
601-
Print *p_print = nullptr;
602609
AudioWriter *p_writer = nullptr;
603610
};
604611

605-
class ContainerTargetAudioPrint : public ContainerTarget {
612+
/**
613+
* @brief ContainerTarget: forwards requests to both the output and the
614+
* encoder/decoder and sets up the output chain for Containers. We also
615+
* manage the proper sequence of the output classes
616+
* @author Phil Schatzmann
617+
* @copyright GPLv3
618+
*/
619+
class ContainerTarget {
606620
public:
607-
ContainerTargetAudioPrint(AudioPrint &print, AudioWriter *writer) {
608-
p_print = &print;
609-
p_writer = writer;
610-
}
611-
virtual bool begin() {
612-
if (p_writer) {
613-
p_writer->begin();
614-
p_writer->setOutputStream(*p_print);
615-
}
616-
return p_print->begin();
617-
}
618-
virtual void end() {
619-
if (p_writer) p_writer->end();
620-
p_print->end();
621-
}
621+
virtual bool begin() = 0;
622+
virtual void end() = 0;
622623
virtual void setAudioInfo(AudioInfo info) {
623-
if (p_writer) p_writer->setAudioInfo(info);
624-
625-
if (p_print->audioInfo() != info) {
626-
p_print->setAudioInfo(info);
624+
if (this->info != info) {
625+
this->info = info;
626+
if (p_writer1 != nullptr) p_writer1->setAudioInfo(info);
627+
if (p_writer2 != nullptr) p_writer2->setAudioInfo(info);
627628
}
628629
}
629-
virtual size_t write(uint8_t *data, size_t size) {
630-
TRACED();
631-
return p_writer ? p_writer->write(data, size) : p_print->write(data, size);
632-
}
630+
virtual size_t write(uint8_t *data, size_t size) = 0;
633631

634632
protected:
635-
AudioPrint *p_print;
636-
AudioWriter *p_writer = nullptr;
633+
AudioInfo info;
634+
AudioWriter *p_writer1 = nullptr;
635+
AudioWriter *p_writer2 = nullptr;
636+
AudioWriterToPrint print2;
637+
bool active = false;
637638
};
638639

639-
class ContainerTargetAudioStream : public ContainerTarget {
640+
class ContainerTargetPrint : public ContainerTarget {
640641
public:
641-
ContainerTargetAudioStream(AudioStream &print, AudioWriter *writer) {
642+
void setupOutput(AudioWriter *writer1, AudioWriter *writer2, Print &print) {
642643
p_print = &print;
643-
p_writer = writer;
644-
}
645-
virtual bool begin() {
646-
if (p_writer) {
647-
p_writer->begin();
648-
p_writer->setOutputStream(*p_print);
649-
}
650-
return p_print->begin();
651-
}
652-
virtual void end() { p_print->end(); }
653-
virtual void setAudioInfo(AudioInfo info) {
654-
if (p_writer) p_writer->setAudioInfo(info);
655-
if (p_print->audioInfo() != info) {
656-
p_print->setAudioInfo(info);
657-
}
658-
}
659-
virtual size_t write(uint8_t *data, size_t size) {
660-
TRACED();
661-
return p_writer ? p_writer->write(data, size) : p_print->write(data, size);
644+
p_writer1 = writer1;
645+
p_writer2 = writer2;
646+
print2.setWriter(p_writer2);
662647
}
663648

664-
protected:
665-
AudioStream *p_print;
666-
AudioWriter *p_writer = nullptr;
667-
};
668-
669-
class ContainerTargetAudioWriter : public ContainerTarget {
670-
public:
671-
ContainerTargetAudioWriter(AudioWriter *writer) {
672-
p_writer = writer;
649+
void setupOutput(AudioWriter *writer1, Print &print) {
650+
p_print = &print;
651+
p_writer1 = writer1;
673652
}
653+
674654
virtual bool begin() {
675-
p_writer->begin();
655+
if (!active) {
656+
active = true;
657+
if (p_writer2 != nullptr) {
658+
p_writer1->setOutputStream(print2);
659+
p_writer2->setOutputStream(*p_print);
660+
p_writer1->begin();
661+
p_writer2->begin();
662+
} else {
663+
p_writer1->setOutputStream(*p_print);
664+
p_writer1->begin();
665+
}
666+
}
676667
return true;
677668
}
678-
virtual void end() { p_writer->end(); }
679-
virtual void setAudioInfo(AudioInfo info) { p_writer->setAudioInfo(info); }
669+
virtual void end() {
670+
if (active) {
671+
if (p_writer1 != nullptr) p_writer1->end();
672+
if (p_writer2 != nullptr) p_writer2->end();
673+
}
674+
active = false;
675+
}
680676
virtual size_t write(uint8_t *data, size_t size) {
681677
TRACED();
682-
return p_writer->write(data, size);
678+
return p_writer1->write(data, size);
683679
}
684680

685681
protected:
686-
AudioWriter *p_writer;
682+
Print *p_print = nullptr;
683+
AudioWriterToPrint print2;
687684
};
688685

689686
} // namespace audio_tools

0 commit comments

Comments
 (0)