Skip to content

Instantly share code, notes, and snippets.

@siddolo
Created May 2, 2025 10:56
Show Gist options
  • Save siddolo/8619bc1f3c87cbd2d7be118e73efd6af to your computer and use it in GitHub Desktop.
Save siddolo/8619bc1f3c87cbd2d7be118e73efd6af to your computer and use it in GitHub Desktop.
Minimal ALSA WAV player
/*
gcc -o alsa_player alsa_player.c -lasound
./alsa_player /path/to/wave_file.wav
Hardcoded wave format: PCM 44.1KHz, Stereo, 16 bit little endian
You need asoundlib.h (libasound2-dev)
*/
#include <stdio.h>
#include <stdlib.h>
#include <alsa/asoundlib.h>
#define PCM_DEVICE "default"
int main(int argc, char *argv[]) {
snd_pcm_t *pcm_handle;
snd_pcm_hw_params_t *params;
snd_pcm_uframes_t frames;
unsigned int sample_rate = 44100;
unsigned int channels = 2;
int format = SND_PCM_FORMAT_S16_LE;
int err;
char *buffer;
FILE *fp;
size_t bytes_read;
// Verifica argomenti
if (argc != 2) {
fprintf(stderr, "Uso: %s <file.wav>\n", argv[0]);
return 1;
}
// Apri file audio
fp = fopen(argv[1], "rb");
if (fp == NULL) {
perror("Impossibile aprire il file audio");
return 1;
}
// Salta l'header WAV (44 byte in un WAV standard)
// Nota: questo è un approccio semplificato, un parser WAV reale dovrebbe leggere i metadati
fseek(fp, 44, SEEK_SET);
// Apri device PCM per la riproduzione
err = snd_pcm_open(&pcm_handle, PCM_DEVICE, SND_PCM_STREAM_PLAYBACK, 0);
if (err < 0) {
fprintf(stderr, "Impossibile aprire il device PCM: %s\n", snd_strerror(err));
fclose(fp);
return 1;
}
// Alloca struttura hardware params
snd_pcm_hw_params_alloca(&params);
// Imposta i parametri di default
err = snd_pcm_hw_params_any(pcm_handle, params);
if (err < 0) {
fprintf(stderr, "Impossibile configurare i parametri: %s\n", snd_strerror(err));
goto cleanup;
}
// Imposta accesso di tipo interleaved
err = snd_pcm_hw_params_set_access(pcm_handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
if (err < 0) {
fprintf(stderr, "Errore impostazione accesso: %s\n", snd_strerror(err));
goto cleanup;
}
// Imposta il formato (16-bit little-endian)
err = snd_pcm_hw_params_set_format(pcm_handle, params, format);
if (err < 0) {
fprintf(stderr, "Errore impostazione formato: %s\n", snd_strerror(err));
goto cleanup;
}
// Imposta i canali (stereo)
err = snd_pcm_hw_params_set_channels(pcm_handle, params, channels);
if (err < 0) {
fprintf(stderr, "Errore impostazione canali: %s\n", snd_strerror(err));
goto cleanup;
}
// Imposta la frequenza di campionamento
err = snd_pcm_hw_params_set_rate_near(pcm_handle, params, &sample_rate, 0);
if (err < 0) {
fprintf(stderr, "Errore impostazione sample rate: %s\n", snd_strerror(err));
goto cleanup;
}
// Applica i parametri hardware
err = snd_pcm_hw_params(pcm_handle, params);
if (err < 0) {
fprintf(stderr, "Impossibile impostare i parametri hardware: %s\n", snd_strerror(err));
goto cleanup;
}
// Ottieni la dimensione dei frame
err = snd_pcm_hw_params_get_period_size(params, &frames, 0);
if (err < 0) {
fprintf(stderr, "Errore nell'ottenere la dimensione dei frame: %s\n", snd_strerror(err));
goto cleanup;
}
// Calcola la dimensione del buffer (4 byte per frame in stereo 16-bit)
size_t buffer_size = frames * channels * 2; /* 2 bytes per sample */
buffer = (char *)malloc(buffer_size);
printf("Riproduzione in corso...\n");
// Ciclo di riproduzione
while ((bytes_read = fread(buffer, 1, buffer_size, fp)) > 0) {
// Se abbiamo letto meno di buffer_size, azzeriamo il resto
if (bytes_read < buffer_size) {
memset(buffer + bytes_read, 0, buffer_size - bytes_read);
}
frames = bytes_read / (channels * 2);
err = snd_pcm_writei(pcm_handle, buffer, frames);
if (err == -EPIPE) {
// EPIPE significa underrun
fprintf(stderr, "Underrun occurred\n");
snd_pcm_prepare(pcm_handle);
} else if (err < 0) {
fprintf(stderr, "Errore dalla funzione writei: %s\n", snd_strerror(err));
} else if (err != (int)frames) {
fprintf(stderr, "Short write (scritti %d frame invece di %ld)\n", err, frames);
}
}
// Aspetta che tutto l'audio sia stato riprodotto
snd_pcm_drain(pcm_handle);
printf("Riproduzione completata.\n");
free(buffer);
cleanup:
snd_pcm_close(pcm_handle);
fclose(fp);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment