* Help to solve pop when sound loops
[not found] <1729870300826364279-webhooks-bot@alsa-project.org>
@ 2024-10-25 15:31 ` GitHub issues - edited
0 siblings, 0 replies; 3+ messages in thread
From: GitHub issues - edited @ 2024-10-25 15:31 UTC (permalink / raw)
To: alsa-devel
alsa-project/alsa-lib issue #417 was edited 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
^ permalink raw reply [flat|nested] 3+ messages in thread
* Help to solve pop when sound loops
@ 2024-10-25 16:03 Charles Mulder
0 siblings, 0 replies; 3+ messages in thread
From: Charles Mulder @ 2024-10-25 16:03 UTC (permalink / raw)
To: alsa-devel
[-- Attachment #1: Type: text/plain, Size: 614 bytes --]
Hi.
I hope this is the correct place to ask for help relating to ALSA's C lib?
I'm working on a wavetable project for college. Please see attached.
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
--
Sent with Tuta; enjoy secure & ad-free emails:
https://tuta.com
[-- Attachment #2: basic_alsa_wavetable.c --]
[-- Type: text/x-csrc, Size: 6471 bytes --]
#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]; /* some random data */
/**
* = ALSA Frames
* Frame is container for sending simultaneous samples.
* - Mono frame contains 1 sample.
* - Stereo frame contains 2 samples.
*
* = ALSA Ring Buffer
* Store outgoing (playback) and incoming (capture, record) samples.
* == Two pointers
* - current processed sample by hardware
* - last processed sample by application.
*/
int main(void) {
// ALSA playback related
int err;
snd_pcm_t *playback_handle; // pcm
snd_pcm_hw_params_t *hw_params;
unsigned int sbits, subformat, tick_time, access, channels, buffer_time, buffer_size, periods, period_time, rate, rate_num, rate_den, val, val2; // @todo more descriptive vars
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);
}
/* Display information about the PCM interface */
if( ALSA_INFO == 1) {
printf("PCM playback_handle name = '%s'\n", snd_pcm_name(playback_handle));
printf("PCM state = %s\n",
snd_pcm_state_name(snd_pcm_state(playback_handle)));
snd_pcm_hw_params_get_access(hw_params, &access);
printf("access type = %s\n", snd_pcm_access_name((snd_pcm_access_t)access));
snd_pcm_hw_params_get_format(hw_params, &format);
printf("format = '%s' (%s)\n",
snd_pcm_format_name((snd_pcm_format_t)format),
snd_pcm_format_description(
(snd_pcm_format_t)format));
snd_pcm_hw_params_get_subformat(hw_params, (snd_pcm_subformat_t *)&subformat);
printf("subformat = '%s' (%s)\n",
snd_pcm_subformat_name((snd_pcm_subformat_t)subformat),
snd_pcm_subformat_description( (snd_pcm_subformat_t)subformat) );
snd_pcm_hw_params_get_channels(hw_params, &channels);
printf("channels = %d\n", channels);
snd_pcm_hw_params_get_rate(hw_params, &rate, NULL);
printf("rate = %d bps\n", rate);
snd_pcm_hw_params_get_period_time(hw_params, &period_time, NULL);
printf("period time = %d us\n", period_time);
snd_pcm_hw_params_get_period_size(hw_params, &period_size, &dir);
printf("period size = %d frames\n", (int)period_size);
snd_pcm_hw_params_get_buffer_time(hw_params, &buffer_time, &dir);
printf("buffer time = %d us\n", buffer_time);
snd_pcm_hw_params_get_buffer_size(hw_params, (snd_pcm_uframes_t *) &buffer_size);
printf("buffer size = %d frames\n", buffer_size);
snd_pcm_hw_params_get_periods(hw_params, &periods, &dir);
printf("periods per buffer = %d frames\n", periods);
// rate numerator and denominator
snd_pcm_hw_params_get_rate_numden(hw_params, &rate_num, &rate_den);
printf("exact rate = %d/%d bps\n", rate_num, rate_den);
sbits = snd_pcm_hw_params_get_sbits(hw_params);
printf("significant bits = %d\n", sbits);
}
// 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
//printf("angle inc: %.4f\n", angle_inc);
//printf("index inc: %.4f\n", index_inc);
// Populate wavetable with a sine wave
for( int n = 0; n < N; n++ ) {
//wavetable[n] = sin( angle_inc * n ); // 0 - 1 range
wavetable[n] = sinuc( angle_inc * n ); // 0 - 255 range
//printf("%d\n", wavetable[n]);
}
// 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;
}
^ permalink raw reply [flat|nested] 3+ messages in thread
* Help to solve pop when sound loops
[not found] <1730889959056958199-webhooks-bot@alsa-project.org>
@ 2024-11-06 10:46 ` GitHub issues - edited
0 siblings, 0 replies; 3+ messages in thread
From: GitHub issues - edited @ 2024-11-06 10:46 UTC (permalink / raw)
To: alsa-devel
alsa-project/alsa-lib issue #417 was edited 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
```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
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2024-11-06 10:46 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <1730889959056958199-webhooks-bot@alsa-project.org>
2024-11-06 10:46 ` Help to solve pop when sound loops GitHub issues - edited
2024-10-25 16:03 Charles Mulder
[not found] <1729870300826364279-webhooks-bot@alsa-project.org>
2024-10-25 15:31 ` GitHub issues - edited
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox