Skip to content

Commit 21c2462

Browse files
committed
experimental TimeInfoStream
1 parent 19b0a57 commit 21c2462

File tree

5 files changed

+105
-3
lines changed

5 files changed

+105
-3
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ void loop(){
9595
9696
```
9797
Each stream has it's own [configuration object](https://pschatzmann.github.io/arduino-audio-tools/html/structaudio__tools_1_1_audio_base_info.html) that should be passed to the begin method. The defaultConfig() method is providing a default proposal which will usually "just work". Please consult
98-
the class documentation for the available configuration parameters. You can also easily adapt any provided examples: If you e.g. replace the I2SStream with the AnalogAudioStream class, you will get analog instead of digital output.
98+
the class documentation for the available configuration parameters. You can also __easily adapt__ any provided examples: If you e.g. replace the I2SStream with the AnalogAudioStream class, you will get analog instead of digital output.
9999

100100
Further examples can be found in the [Wiki](https://github.com/pschatzmann/arduino-audio-tools/wiki/Examples).
101101

src/AudioTools/AudioOutput.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class AudioPrint : public Print, public AudioBaseInfoDependent, public AudioBase
5656
return false;
5757
}
5858

59-
virtual AudioBaseInfo audioInfo() {
59+
virtual AudioBaseInfo audioInfo() override {
6060
return cfg;
6161
}
6262

src/AudioTools/AudioStreams.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ class AudioStream : public Stream, public AudioBaseInfoDependent, public AudioBa
6262

6363
operator bool() { return available() > 0; }
6464

65-
virtual AudioBaseInfo audioInfo() {
65+
virtual AudioBaseInfo audioInfo() override {
6666
return info;
6767
}
6868

src/AudioTools/AudioTypes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ class AudioBaseInfoDependent {
6363
public:
6464
virtual ~AudioBaseInfoDependent(){}
6565
virtual void setAudioInfo(AudioBaseInfo info)=0;
66+
virtual AudioBaseInfo audioInfo() = 0;
6667
virtual bool validate(AudioBaseInfo &info){
6768
return true;
6869
}

src/Experiments/TimeInfoStream.h

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
#pragma once
2+
3+
#include "AudioTools/AudioStreams.h"
4+
5+
namespace audio_tools {
6+
7+
/**
8+
* @brief Wrapper class that can define a start and (an optional) stop time
9+
* Only wrap classes which represent PCM data!
10+
* @author Phil Schatzmann
11+
* @copyright GPLv3
12+
*/
13+
class TimeInfoStream : public AudioStreamX {
14+
public:
15+
TimeInfoStream(AudioStream &io, long startSeconds=0, long endSeconds=-1){
16+
p_stream = &io;
17+
p_print = &io;
18+
p_info = &io;
19+
start_time = startSeconds;
20+
end_time = endSeconds;
21+
}
22+
23+
TimeInfoStream(AudioPrint &o,long startSeconds=0, long endSeconds=-1){
24+
p_print = &o;
25+
p_info = &o;
26+
start_time = startSeconds;
27+
end_time = endSeconds;
28+
}
29+
30+
void setStartTime(long startSeconds){
31+
start_time = startSeconds;
32+
}
33+
34+
void setEndTime(long endSeconds){
35+
end_time = endSeconds;
36+
}
37+
38+
/// Resets the current time
39+
void setCurrentTime(double timeScalculateTimeeStartSeconds=0) {
40+
current_time = timeScalculateTimeeStartSeconds;
41+
bytes_per_second = -1.0; // trigger new calculation
42+
}
43+
44+
/// Provides the current time in seconds from the start
45+
double currentTime() {
46+
return current_time;
47+
}
48+
49+
/// Returns true if we are in a valid time range and are still playing sound
50+
bool isPlaying() {
51+
if (current_time<start_time) return false;
52+
if (end_time>0 && current_time>end_time) return false;
53+
return true;
54+
}
55+
56+
/// Returns true if we are not past the end time;
57+
bool isActive() {
58+
if (end_time>0 && current_time>end_time) return false;
59+
return true;
60+
}
61+
62+
operator bool() {
63+
return isActive();
64+
}
65+
66+
size_t readBytes(uint8_t *buffer, size_t length) override {
67+
if (p_stream==nullptr) return 0;
68+
calculateTime(length);
69+
return isPlaying()?p_stream->readBytes(buffer, length):length;
70+
}
71+
72+
size_t write(const uint8_t *buffer, size_t length) override{
73+
calculateTime(length);
74+
return isPlaying()?p_print->write(buffer, length):length;
75+
}
76+
77+
int available() override { return p_stream!=nullptr ? p_stream->available():0; };
78+
int availableForWrite() override { return p_print->availableForWrite(); }
79+
80+
protected:
81+
Stream *p_stream=nullptr;
82+
Print *p_print=nullptr;
83+
AudioBaseInfoDependent *p_info=nullptr;
84+
long start_time = 0;
85+
long end_time = -1;
86+
double current_time = 0;
87+
double bytes_per_second = -1.0;
88+
89+
void calculateTime(int bytes){
90+
if (bytes_per_second<0.0){
91+
int channels = p_info->audioInfo().channels;
92+
int sample_rate = p_info->audioInfo().sample_rate; // frames per second
93+
int bytes_per_sample = p_info->audioInfo().bits_per_sample / 8;
94+
bytes_per_second = sample_rate * channels * bytes_per_sample;
95+
}
96+
current_time = static_cast<double>(bytes) / bytes_per_second;
97+
}
98+
99+
};
100+
101+
}

0 commit comments

Comments
 (0)