@@ -46,6 +46,10 @@ class SoundGenerator {
46
46
LOGI (" bits_per_sample: %d" , info.bits_per_sample );
47
47
LOGI (" channels: %d" , info.channels );
48
48
LOGI (" sample_rate: %d" , info.sample_rate );
49
+
50
+ // support bytes < framesize
51
+ ring_buffer.resize (info.channels *sizeof (T));
52
+
49
53
return true ;
50
54
}
51
55
@@ -59,64 +63,19 @@ class SoundGenerator {
59
63
return active;
60
64
}
61
65
62
- // / Provides the samples into simple array - which represents 1 channel
63
- virtual size_t readSamples (T* data, size_t sampleCount=512 ){
64
- for (size_t j=0 ;j<sampleCount;j++){
65
- data[j] = readSample ();
66
- }
67
- return sampleCount;
68
- }
69
-
70
- // / Provides the samples into a 2 channel array
71
- virtual size_t readSamples (T src[][2 ], size_t frameCount) {
72
- T tmp[frameCount];
73
- int len = readSamples (tmp, frameCount);
74
- for (int j=0 ;j<len;j++) {
75
- T value = tmp[j];
76
- src[j][1 ] = src[j][0 ] = value;
77
- }
78
- return frameCount;
79
- }
80
-
81
66
// / Provides a single sample
82
67
virtual T readSample () = 0;
83
68
84
69
// / Provides the data as byte array with the requested number of channels
85
70
virtual size_t readBytes ( uint8_t *buffer, size_t lengthBytes){
86
- // LOGD("readBytes: %d", (int)lengthBytes);
87
- size_t result = 0 ;
88
- int ch = audioInfo ().channels ;
89
- if (ch==0 ){
90
- LOGE (" Undefine number of channels: %d" ,ch);
91
- ch = 1 ;
92
- }
93
- int frame_size = sizeof (T) * ch;
94
- if (active){
95
- int len = lengthBytes / frame_size;
96
- if (lengthBytes % frame_size!=0 ){
97
- len++;
98
- }
99
- switch (ch){
100
- case 1 :
101
- result = readSamples ((T*) buffer, len) ;
102
- break ;
103
- case 2 :
104
- result = readSamples ((T (*)[2 ]) buffer, len);
105
- break ;
106
- default :
107
- LOGE ( " SoundGenerator::readBytes -> number of channels %d is not supported (use 1 or 2)" , ch);
108
- result = 0 ;
109
- break ;
110
- }
111
- } else {
112
- if (!activeWarningIssued) {
113
- LOGE (" SoundGenerator::readBytes -> inactive" );
114
- activeWarningIssued=true ;
115
- }
116
- result = 0 ;
71
+ LOGD (" readBytes: %d" , (int )lengthBytes);
72
+ int channels = audioInfo ().channels ;
73
+ int frame_size = sizeof (T) * channels;
74
+ int frames = lengthBytes / frame_size;
75
+ if (lengthBytes>=frame_size){
76
+ return readBytesFrames (buffer, lengthBytes, frames, channels);
117
77
}
118
- // LOGD( "SoundGenerator::readBytes (channels: %d) %zu bytes -> %zu samples", ch, lengthBytes, result);
119
- return result * frame_size;
78
+ return readBytesFromBuffer (buffer, lengthBytes, frame_size, channels);
120
79
}
121
80
122
81
virtual AudioBaseInfo defaultConfig (){
@@ -148,6 +107,31 @@ class SoundGenerator {
148
107
bool activeWarningIssued = false ;
149
108
int output_channels = 1 ;
150
109
AudioBaseInfo info;
110
+ RingBuffer<uint8_t > ring_buffer{0 };
111
+
112
+ size_t readBytesFrames (uint8_t *buffer, size_t lengthBytes, int frames, int channels ){
113
+ T* result_buffer = (T*)buffer;
114
+ for (int j=0 ;j<frames;j++){
115
+ T sample = readSample ();
116
+ for (int ch=0 ;ch<channels;ch++){
117
+ *result_buffer++ = sample;
118
+ }
119
+ }
120
+ return frames*sizeof (T);
121
+ }
122
+
123
+ size_t readBytesFromBuffer (uint8_t *buffer, size_t lengthBytes, int frame_size, int channels) {
124
+ // fill ringbuffer with one frame
125
+ if (ring_buffer.isEmpty ()){
126
+ uint8_t tmp[frame_size];
127
+ readBytesFrames (tmp, frame_size, 1 , channels);
128
+ ring_buffer.writeArray (tmp, frame_size);
129
+ }
130
+ // provide result
131
+ return ring_buffer.readArray (buffer, lengthBytes);
132
+ }
133
+
134
+
151
135
152
136
};
153
137
0 commit comments