J Romuald J Romuald - 29 days ago 8
C Question

C progam to play audio file in Linux crackels at end

On Ubuntu Linux I have written a c program based on the Libao example program to open audio wave file and play. It works fine but at the end after finish playing there is crackling high pitch noise. Here is the code which I modified mt libao example. How can I fix it? Please help

#include <stdio.h>
#include <string.h>
#include <ao/ao.h>
#include <math.h>
#define BUF_SIZE 4096

int main(int argc, char **argv)
{
ao_device *device;
ao_sample_format format;
int default_driver;
char *buffer;
int buf_size;
int sample;
FILE *fp;

float freq = 440.0;
int i;
/* -- Initialize -- */
fprintf(stderr, "libao example program\n");
ao_initialize();
/* -- Setup for default driver -- */
default_driver = ao_default_driver_id();
memset(&format, 0, sizeof(format));
format.bits = 16;
format.channels = 2;
format.rate = 44100;
format.byte_format = AO_FMT_LITTLE;
/* -- Open driver -- */
// device = ao_open_live(default_driver, &format, NULL /* no options */);
device = ao_open_live(default_driver, &format, NULL /* no options */);

if (device == NULL) {
fprintf(stderr, "Error opening device.\n");
return 1;
}


fp = fopen("nc.wav", "rb");
if (fp == NULL) {
fprintf(stderr, "Unable to open file \n");
return;
}

fseek(fp, 0, SEEK_END);
unsigned long fileLen = ftell(fp);
fseek(fp, 0, SEEK_SET);

//Allocate memory
buffer=(char *)malloc(fileLen+1);

if (!buffer)
{
fprintf(stderr, "Memory error!");
fclose(fp);
return;
}



fread(buffer, fileLen, 1, fp);
fclose(fp);

ao_play(device, buffer, buf_size);
/* -- Close and shutdown -- */
ao_close(device);
ao_shutdown();
return (0);
}

Answer

The buf_size variable is passed to ao_play without being initialized, and the crackles most likely occur because it is playing past the end of the sample buffer into random memory.

Depending on your compiler settings, the compiler can warn you about bugs like this (gcc only does it when optimizations are turned on).