- Reducing Clicks and Humps on the Speaker

This commit is contained in:
tudnai
2020-05-17 16:01:15 -07:00
parent 846df28a07
commit c8f09f878d
3 changed files with 43 additions and 23 deletions

View File

@@ -67,6 +67,9 @@ const unsigned spkr_buf_size = spkr_seconds * spkr_sample_rate / spkr_fps;
char spkr_samples [ spkr_buf_size * spkr_fps * 2]; // 1s of sound char spkr_samples [ spkr_buf_size * spkr_fps * 2]; // 1s of sound
unsigned spkr_sample_idx = 0; unsigned spkr_sample_idx = 0;
const unsigned spkr_play_timeout = 10;
unsigned spkr_play_time = 0;
#define BUFFER_COUNT 10 #define BUFFER_COUNT 10
#define SOURCES_COUNT 1 #define SOURCES_COUNT 1
@@ -132,7 +135,7 @@ ALint freeBuffers = BUFFER_COUNT;
//ALuint alBuffers[BUFFER_COUNT]; //ALuint alBuffers[BUFFER_COUNT];
void spkr_update() { void spkr_update() {
if ( spkr_sample_idx ) { if ( spkr_play_time ) {
// printf("freeBuffers: %d", freeBuffers); // printf("freeBuffers: %d", freeBuffers);
@@ -182,16 +185,35 @@ void spkr_update() {
// Download buffer to OpenAL // Download buffer to OpenAL
// memcpy(spkr_samples + spkr_buf_size, spkr_samples + spkr_buf_size - spkr_extra_buf, spkr_extra_buf); if ( --spkr_play_time == 0 ) {
alBufferData(spkr_buffers[freeBuffers - 1], AL_FORMAT_MONO8, spkr_samples, spkr_buf_size + spkr_extra_buf, spkr_sample_rate); // we need to soft mute the speaker to eliminate clicking noise
al_check_error(); // simple linear mute
int step = (SPKR_LEVEL_ZERO - (int)spkr_level) / 128;
alSourceQueueBuffers(spkr_src, 1, &spkr_buffers[freeBuffers - 1]); if ( step != 0 ) {
// al_check_error(); for ( spkr_sample_idx = 0; spkr_level != SPKR_LEVEL_ZERO; spkr_level += step) {
for ( int i = 0; i < 4; i++ ) {
// ALint secoffset = 0; spkr_samples[ spkr_sample_idx++ ] = spkr_level;
// alGetSourcei( spkr_src, AL_BYTE_OFFSET, &secoffset ); }
}
spkr_level = SPKR_LEVEL_ZERO;
spkr_samples[ spkr_sample_idx++ ] = spkr_level;
//spkr_samples[sample_idx] = spkr_level;
memset(spkr_samples + spkr_sample_idx, spkr_level, spkr_extra_buf);
freeBuffers--;
alBufferData(spkr_buffers[freeBuffers], AL_FORMAT_MONO8, spkr_samples, spkr_sample_idx, spkr_sample_rate);
al_check_error();
alSourceQueueBuffers(spkr_src, 1, &spkr_buffers[freeBuffers]);
al_check_error();
}
}
else {
freeBuffers--;
alBufferData(spkr_buffers[freeBuffers], AL_FORMAT_MONO8, spkr_samples, spkr_buf_size + spkr_extra_buf, spkr_sample_rate);
al_check_error();
alSourceQueueBuffers(spkr_src, 1, &spkr_buffers[freeBuffers]);
al_check_error();
}
switch (state) { switch (state) {
case AL_PAUSED: case AL_PAUSED:
@@ -208,24 +230,15 @@ void spkr_update() {
break; break;
} }
// // copy slack buffer to the top, so we will not lose the edges
// memcpy(spkr_samples, spkr_samples + secoffset, spkr_buf_size - secoffset);
// // clear the slack buffer , so we can fill it up by new data
// memset(spkr_samples + secoffset, spkr_level, spkr_buf_size - secoffset);
// clear the slack buffer , so we can fill it up by new data // clear the slack buffer , so we can fill it up by new data
memset(spkr_samples, spkr_level, spkr_buf_size); memset(spkr_samples, spkr_level, spkr_buf_size + spkr_extra_buf);
// start from the beginning // start from the beginning
spkr_sample_idx = 0; spkr_sample_idx = 0;
// if ( freeBuffers > 0 ) {
freeBuffers--;
// }
} }
// else { else {
// // TODO: Need better speaker turn off logic to avoid click noise // TODO: Need better speaker turn off logic to avoid click noise
//// if ( spkr_src ) { //// if ( spkr_src ) {
//// alSourceStop(spkr_src); //// alSourceStop(spkr_src);
//// al_check_error(); //// al_check_error();
@@ -238,7 +251,7 @@ void spkr_update() {
//// memset(spkr_samples, spkr_level, spkr_buf_size); //// memset(spkr_samples, spkr_level, spkr_buf_size);
//// } //// }
//// printf("freeBuffers_nosound: %d\n", freeBuffers); //// printf("freeBuffers_nosound: %d\n", freeBuffers);
// } }
} }

View File

@@ -13,6 +13,7 @@
#define SPKR_LEVEL_MIN 0 #define SPKR_LEVEL_MIN 0
#define SPKR_LEVEL_MAX 255 #define SPKR_LEVEL_MAX 255
#define SPKR_LEVEL_ZERO ( SPKR_LEVEL_MIN + SPKR_LEVEL_MAX / 2 )
extern void spkr_init(void); extern void spkr_init(void);
extern void spkr_exit(void); extern void spkr_exit(void);
@@ -27,5 +28,9 @@ extern int spkr_level;
extern int freeBuffers; extern int freeBuffers;
extern unsigned spkr_extra_buf; extern unsigned spkr_extra_buf;
extern const unsigned spkr_play_timeout;
extern unsigned spkr_play_time;
#endif /* speaker_h */ #endif /* speaker_h */

View File

@@ -404,6 +404,8 @@ INLINE void spkr_switch() {
// TODO: This is very slow! // TODO: This is very slow!
// printf("io_KBDSTRB\n"); // printf("io_KBDSTRB\n");
spkr_play_time = spkr_play_timeout;
// push a click into the speaker buffer // push a click into the speaker buffer
// (we will play the entire buffer at the end of the frame) // (we will play the entire buffer at the end of the frame)
spkr_sample_idx = clkfrm / (default_MHz_6502 / spkr_sample_rate); spkr_sample_idx = clkfrm / (default_MHz_6502 / spkr_sample_rate);