Skip to content

Commit

Permalink
MeasuringStream
Browse files Browse the repository at this point in the history
  • Loading branch information
pschatzmann committed Nov 9, 2023
1 parent 27c340e commit 97f1508
Show file tree
Hide file tree
Showing 2 changed files with 1 addition and 125 deletions.
124 changes: 0 additions & 124 deletions src/AudioTools/AudioIO.h
Original file line number Diff line number Diff line change
Expand Up @@ -305,129 +305,5 @@ class TimedStream : public AudioStream {
}
};

/**
* Measures the effective output sample rate that flows thru the input or
* output chain: We specify the n.th io time at which we calculate the rate with
* the help of the setReportAt() method.
*
* @author Phil Schatzmann
* @version 0.1
* @date 2023-10-28
* @copyright Copyright (c) 2023
*/
class RateMeasuringStream : public AudioStream {
public:
RateMeasuringStream() = default;
RateMeasuringStream(Print &out) { setOutput(out); }
RateMeasuringStream(Stream &out) { setStream(out); }

/// Defines the output
void setOutput(Print &out) { setStream(out); }

/// Defines the output
void setStream(Print &out) { p_out = &out; }
void setStream(Stream &stream) {
p_out = &stream;
p_stream = &stream;
}

/// We need to warm up to find a stable value: here we define the count at
/// which we measure
void setReportAt(int at) { count_at = at; }

/// Defines an alternative method to determine millis()
void setTimeCallback(uint32_t (*cb_ms)(void)) { millis_cb = cb_ms; }

int availableForWrite() override {
if (p_out == nullptr)
return 0;
return p_out->availableForWrite();
}

size_t write(const uint8_t *data, size_t len) override {
if (p_out == nullptr)
return 0;
if (counter == 0 && len > 0) {
start_time = ms();
}
size_t result = p_out->write(data, len);
if (isActvie()) {
last_time = ms();
total_bytes += result;
}
counter++;
return result;
}

int available() override {
if (p_stream == nullptr)
return 0;
return p_stream->available();
}

size_t readBytes(uint8_t *data, size_t len) override {
if (p_stream == nullptr)
return 0;
if (counter == 0 && len > 0) {
start_time = ms();
}
size_t result = p_stream->readBytes(data, len);
if (isActvie()) {
last_time = ms();
total_bytes += result;
}
counter++;
return result;
}

/// provides the effective sample rate in server time
float sampleRate() {
// if we did not reach the limit we report the to be rate
if (counter < count_at)
return info.sample_rate;
// report the effective rate
float time_ms = last_time - start_time;
float bytes_per_second = static_cast<float>(total_bytes) / time_ms / 1000.0;
float frame_size = info.bits_per_sample * info.channels / 8;
// calculate frames (=samples) per second
return bytes_per_second / frame_size;
}

/// Calculates the correction factor to adjust the sample rate
float correctionFactor() {
// e.g. to be 44100 , eff 44110 -> 0.99977329403 (we need to slow down a
// bit)
return static_cast<float>(info.sample_rate) / sampleRate();
}

/// Provides true if we can provide a measured value
bool isResultValid() { return counter >= count_at; }

/// Provides true if we reached the update count
bool isUpdate() { return counter == count_at; }

void logResult() {
LOGI("Sample rate: %d, effective: %f -> correction %f", info.sample_rate, sampleRate(), correctionFactor());
}

bool isActvie() { return counter <= count_at; }

protected:
const char *TAG = "SNAP";
Stream *p_stream = nullptr;
Print *p_out = nullptr;
uint32_t counter = 0;
uint32_t count_at = -1;
uint32_t start_time = 0;
uint32_t last_time = 0;
uint32_t total_bytes = 0;
uint32_t (*millis_cb)(void) = nullptr;

inline uint32_t ms() {
if (millis_cb)
return millis_cb();
return millis();
}
};

} // namespace audio_tools
2 changes: 1 addition & 1 deletion src/AudioTools/AudioStreams.h
Original file line number Diff line number Diff line change
Expand Up @@ -1092,7 +1092,7 @@ class MeasuringStream : public AudioStream {
count--;
total_bytes+=len;

if (count<0){
if (count<=0){
uint32_t end_time = millis();
int time_diff = end_time - start_time; // in ms
if (time_diff>0){
Expand Down

0 comments on commit 97f1508

Please sign in to comment.