alsa-project/alsa-lib issue #417 was opened from charlesmulder: Hi. Apologies for asking for help here. I don't know where else to go. I'm working on a wavetable project for college. I've managed to create a wavetable containing a sine wave. The pitch can be altered via a frequency variable (f). There is an audible popping sound when the sound loops. I have noticed that increasing the buffer size, postpones the pop. I've been reading up on `buffer > period > frames`, but I don't know how to go about removing the pop. Would really appreciate some guidance. Thanks C ``` #include <stdio.h> #include <alsa/asoundlib.h> #include <math.h> unsigned char sinuc( float ); #define TWOPI 2*M_PI #define ALSA_INFO 1 static char *device = "default"; /* playback device */ unsigned char buffer[24*1024]; int main(void) { // ALSA playback related int err; snd_pcm_t *playback_handle; // pcm snd_pcm_hw_params_t *hw_params; unsigned int val, val2; int dir; snd_pcm_uframes_t period_size; snd_pcm_format_t format; // Wavetable related unsigned int N = 1024; float f = 440; // A4 note //float f = 261.626; // C4 note unsigned int fs = 44100; // playback if ((err = snd_pcm_open(&playback_handle, device, SND_PCM_STREAM_PLAYBACK, 0)) < 0) { printf("Playback open error: %s\n", snd_strerror(err)); exit(EXIT_FAILURE); } // ALSA configuration /* Allocate a hardware parameters object. */ snd_pcm_hw_params_alloca(&hw_params); /* Fill it in with default values. */ snd_pcm_hw_params_any(playback_handle, hw_params); /* Set the desired hardware parameters. */ /* Interleaved mode */ snd_pcm_hw_params_set_access(playback_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED); /* Unsigned 8-bit little-endian format */ snd_pcm_hw_params_set_format(playback_handle, hw_params, SND_PCM_FORMAT_U8); /* Two channels (stereo) */ snd_pcm_hw_params_set_channels(playback_handle, hw_params, 1); /* 44100 bits/second sampling rate (CD quality) */ snd_pcm_hw_params_set_rate_near(playback_handle, hw_params, &fs, &dir); /* Set period size to 32 frames. */ period_size = 32; snd_pcm_hw_params_set_period_size_near(playback_handle, hw_params, &period_size, &dir); /* Write the parameters to the driver */ err = snd_pcm_hw_params(playback_handle, hw_params); if (err < 0) { fprintf(stderr, "unable to set hw parameters: %s\n", snd_strerror(err)); exit(1); } // Wavetable init unsigned char wavetable[N]; // wavetable buffer float angle_inc = TWOPI/(float)N; // sine wave angle increment float index_inc = N*f/(float)fs; // wavetable index increment // Populate wavetable with a sine wave for( int n = 0; n < N; n++ ) { wavetable[n] = sinuc( angle_inc * n ); // 0 - 255 range } // ALSA Sample Buffer // period = 940 frames // buffer = 15052 frames float n = 0; for (int i = 0; i < sizeof(buffer)/sizeof(char); i++) { buffer[i] = wavetable[(int)n]; //printf("%d\n",buffer[i]); n = n+index_inc; if( (int)n >= N ) { n = 0; } } if ((err = snd_pcm_prepare (playback_handle)) < 0) { fprintf (stderr, "cannot prepare audio interface for use (%s)\n", snd_strerror (err)); exit (1); } //for (int i = 0; i < 16; i++) { while(1) { period_size = snd_pcm_writei(playback_handle, buffer, sizeof(buffer)); if (period_size < 0) period_size = snd_pcm_recover(playback_handle, period_size, 0); if (period_size < 0) { printf("snd_pcm_writei failed: %s\n", snd_strerror(period_size)); break; } if (period_size > 0 && period_size < (long)sizeof(buffer)) printf("Short write (expected %li, wrote %li)\n", (long)sizeof(buffer), period_size); } // pass the remaining samples, otherwise they're dropped in close err = snd_pcm_drain(playback_handle); if (err < 0) printf("snd_pcm_drain failed: %s\n", snd_strerror(err)); //snd_pcm_hw_params_free(hw_params); snd_pcm_close(playback_handle); return 0; } /** * Sine unsigned char. * Scales sine output to a char * Original range -1 to 1. * New range 0 - 255. */ unsigned char sinuc( float angle ) { return (sinf( angle ) * 255 + 255) / 2; } ``` Issue URL : https://github.com/alsa-project/alsa-lib/issues/417 Repository URL: https://github.com/alsa-project/alsa-lib