|
Here is code from John R. Hall's book Programming Linux Games. The following method, called LoadSoundFile, would not compile for me. I finally got it to compile, but then it took a very long time to successfully call the alBufferData function. I fixed that by writing the following code, which also runs without error but which is much faster. The original file was resources.c from pw-final. - Charlie Calvert |
#include <AL/alut.h>
/*
* Loads a sound file into a sound structure and sends the data to OpenAL.
* This code is mostly derived from libsndfile example code in Chapter 5.
*/
int LoadSoundFile(char *filename, sound_p sound)
{
ALvoid *data;
ALsizei freq;
ALboolean loop;
printf("Giving data to AL\n");
/* Give our sound data to OpenAL. */
alGenBuffers(1, &sound->name);
if (alGetError() != AL_NO_ERROR)
{
printf("Error creating an AL buffer name for %s.\n", filename);
goto error_cleanup;
}
alutLoadWAVFile(filename, &sound->format, &data, &sound->size, &freq, &loop);
printf("Sending data to AL\n");
alBufferData(sound->name, sound->format, data, sound->size, freq);
if (alGetError() != AL_NO_ERROR)
{
printf("Error sending buffer data to OpenAL for %s.\n", filename);
goto error_cleanup;
}
alutUnloadWAV(sound->format, data, sound->size, freq);
printf("Finsihed sending data to AL\n");
/* Close the file and return success. */
printf("closed files\n");
return 0;
error_cleanup:
printf("error cleanup\n");
return -1;
}
|
And here is the code that I got to work, but which ran slowly. I'm sure one of the paramters on the call to alBufferData is wrong, but in the process of figuring out what was wrong, I found the solution above, which is cleaner. So I never did fix this code, which does run without error, albiet very slowly: |
/* Open the file and retrieve sample information. */
//file = sf_open_read(filename, &file_info); //csc
file = sf_open(filename, SFM_READ, &file_info);
if (file == NULL)
{
printf("CSCUnable to open '%s'.\n", filename);
return -1;
}
/* Make sure the format is acceptable. csc I've added S8
if ((file_info.format & 0x0F) != SF_FORMAT_PCM_S8)
{
printf("'%s' is not a PCM-based audio file.\n", filename);
sf_close(file);
return -1;
} */
printf("Sample format %d in %s.\n", file_info.format & 0x0F, filename);
if (( (file_info.format) == SF_FORMAT_PCM_S8) && (file_info.channels == 1))
{
sound->format = AL_FORMAT_MONO8;
}
else if (( (file_info.format & 0x0F) == SF_FORMAT_PCM_S8) && (file_info.channels == 2))
{
sound->format = AL_FORMAT_STEREO8;
}
else if (( (file_info.format & 0x0F) == SF_FORMAT_PCM_16) && (file_info.channels == 1))
{
sound->format = AL_FORMAT_MONO16;
}
else if (( (file_info.format & 0x0F) == SF_FORMAT_PCM_16) && (file_info.channels == 2))
{
sound->format = AL_FORMAT_STEREO16;
}
else
{
printf("Unknown sample format %d in %s.\n", file_info.format & 0x0F, filename);
sf_close(file);
return -1;
}
/* Allocate buffers. */
buffer_short = (short *)malloc(file_info.frames *
file_info.channels *
sizeof (short));
buffer_8 = (u_int8_t *)malloc(file_info.frames *
file_info.channels *
file_info.format / 8);
buffer_16 = (int16_t *)buffer_8;
if (buffer_short == NULL || buffer_8 == NULL)
{
printf("Unable to allocate enough memory for '%s'.\n", filename);
goto error_cleanup;
}
/* Read the entire sound file. */
if (sf_readf_short(file,buffer_short,file_info.frames) == (size_t)-1)
{
printf("Error while reading samples from '%s'.\n", filename);
goto error_cleanup;
}
printf("Converting\n");
/* Convert the data to the correct format. */
for (i = 0; i < file_info.frames * file_info.channels; i++)
{
if (file_info.format == SF_FORMAT_PCM_S8)
{
/* Convert the sample from a signed short to an unsigned byte */
buffer_8[i] = (u_int8_t)((short)buffer_short[i] + 128);
}
else
{
buffer_16[i] = (int16_t)buffer_short[i];
//short a = buffer_short[i];
}
}
printf("Finsished Converting\n");
/* Fill in the sound data structure. */
sound->freq = file_info.samplerate;
sound->size = file_info.frames * file_info.channels * file_info.format / 8;
printf("Giving data to AL\n");
/* Give our sound data to OpenAL. */
alGenBuffers(1, &sound->name);
if (alGetError() != AL_NO_ERROR)
{
printf("Error creating an AL buffer name for %s.\n", filename);
goto error_cleanup;
}