Skip to content

Commit 676c95c

Browse files
committed
DynamicMemoryStream loop correction
1 parent 8722181 commit 676c95c

File tree

2 files changed

+123
-1
lines changed

2 files changed

+123
-1
lines changed

src/AudioTools/AudioStreams.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,13 @@ class DynamicMemoryStream : public AudioStreamX {
416416
}
417417

418418
virtual int available() override {
419-
return it == audio_list.end() ? 0 : (*it)->len;
419+
if (it == audio_list.end()){
420+
if (is_loop) rewind();
421+
if (it == audio_list.end()) {
422+
return 0;
423+
}
424+
}
425+
return (*it)->len;
420426
}
421427

422428
virtual size_t readBytes(uint8_t *buffer, size_t length) override {
@@ -450,6 +456,10 @@ class DynamicMemoryStream : public AudioStreamX {
450456
return result_len;
451457
}
452458

459+
List<DataNode*> &list() {
460+
return audio_list;
461+
}
462+
453463
protected:
454464
List<DataNode*> audio_list;
455465
List<DataNode*>::Iterator it = audio_list.end();

src/AudioTools/Converter.h

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -848,5 +848,117 @@ class SilenceRemovalConverter : public BaseConverter<T> {
848848
}
849849
};
850850

851+
/**
852+
* @brief Big value gaps (at the beginning and the end of a recording) can lead to some popping sounds.
853+
* We will try to set the values to 0 until the first transition thru 0 of the audio curve
854+
*
855+
* @tparam T
856+
*/
857+
template<typename T>
858+
class PoppingSoundRemover : public BaseConverter<T> {
859+
public:
860+
PoppingSoundRemover(int channels, bool fromBeginning, bool fromEnd){
861+
this->channels = channels;
862+
from_beginning = fromBeginning;
863+
from_end = fromEnd;
864+
}
865+
virtual size_t convert(uint8_t *src, size_t size) {
866+
for (int ch=0;ch<channels;ch++){
867+
if (from_beginning)
868+
clearUpTo1stTransition(channels, ch, (T*) src, size/sizeof(T));
869+
if (from_end)
870+
clearAfterLastTransition(channels, ch, (T*) src, size/sizeof(T));
871+
}
872+
return size;
873+
}
874+
875+
protected:
876+
bool from_beginning;
877+
bool from_end;
878+
int channels;
879+
880+
void clearUpTo1stTransition(int channels, int channel, T* values, int sampleCount){
881+
T first = values[channel];
882+
for (int j=0;j<sampleCount;j+=channels){
883+
T act = values[j];
884+
if (first <= 0.0 && act >= 0.0 || first>=0.0 && act <= 0.0){
885+
// we found the last transition so we are done
886+
break;
887+
} else {
888+
values[j] = 0;
889+
}
890+
}
891+
}
892+
893+
void clearAfterLastTransition(int channels, int channel, T* values, int sampleCount){
894+
int lastPos = sampleCount - channels + channel;
895+
T last = values[lastPos];
896+
for (int j=lastPos;j>=0;j-=channels){
897+
T act = values[j];
898+
if (last <= 0.0 && act >= 0.0 || last>=0.0 && act <= 0.0){
899+
// we found the last transition so we are done
900+
break;
901+
} else {
902+
values[j] = 0;
903+
}
904+
}
905+
}
906+
};
907+
908+
/**
909+
* @brief Changes the samples at the beginning or at the end to slowly ramp up the volume
910+
*
911+
* @tparam T
912+
*/
913+
template<typename T>
914+
class SmoothTransition : public BaseConverter<T> {
915+
public:
916+
SmoothTransition(int channels, bool fromBeginning, bool fromEnd, float inc=0.01){
917+
this->channels = channels;
918+
this->inc = inc;
919+
from_beginning = fromBeginning;
920+
from_end = fromEnd;
921+
}
922+
virtual size_t convert(uint8_t *src, size_t size) {
923+
for (int ch=0;ch<channels;ch++){
924+
if (from_beginning)
925+
processStart(channels, ch, (T*) src, size/sizeof(T));
926+
if (from_end)
927+
processEnd(channels, ch, (T*) src, size/sizeof(T));
928+
}
929+
return size;
930+
}
931+
932+
protected:
933+
bool from_beginning;
934+
bool from_end;
935+
int channels;
936+
float inc=0.01;
937+
float factor = 0;
938+
939+
void processStart(int channels, int channel, T* values, int sampleCount){
940+
for (int j=0;j<sampleCount;j+=channels){
941+
if (factor>=0.8){
942+
break;
943+
} else {
944+
values[j]*=factor;
945+
}
946+
factor += inc;
947+
}
948+
}
949+
950+
void processEnd(int channels, int channel, T* values, int sampleCount){
951+
int lastPos = sampleCount - channels + channel;
952+
for (int j=lastPos;j>=0;j-=channels){
953+
if (factor>=0.8){
954+
break;
955+
} else {
956+
values[j]*=factor;
957+
}
958+
}
959+
}
960+
};
961+
962+
851963

852964
}

0 commit comments

Comments
 (0)