Using SDL to make a WAV Resource creator

Hi,

Okay so maybe I’m still a noob, but here is how I figured this one out…

I have been wanting to store all my wav sounds in one single resource file, so I decided to create my own resource creator. Basically, using SDL, I load the WAV file into memory, then take all the raw data and store it in my own created file. Pros : my sound files are now hidden from the player. Cons : The resource file is huge, as no compression has been done. If anyone has any ideas on how to compress (like maybe look for repetetive data) please let me know any handy algorithms :))

Any feedback is also appreciated, but please be gentle LOL, I’m still new at all this.

-K

Could you not convert the wavs to ogg or mp3 files instead?

hi,

I haven’t tried that, but in theory SDL will decompress the OGG or MP3 file before saving it to my resource file anyway, so either way I still stuck with a large resource file. I preferrably don’t want all my sound files exposed in the game folder, I am trying to put 10 or so audio files into one single file and call it Audio.1, Audio.2, etc…

I will however give the OGG version a try and see the result, thanks for your input :slight_smile:

K

okay, i tried using ogg, mp3 etc files, but like i suspected, SDL decompresses the files into a raw format in memory.

To elaborate more on what I am doing, here is some code :

Mix_Chunk* test(nullptr);
test = Mix_LoadWAV(“nameofaudiofile.WAV”);

now the test pointer points to the uncompressed audio data in memory. I know the “abuf” member variable points to all the actual audio data, which is merely loads and loads of 8-bit values.

i then write all of test’s data to file :

file.write((char*)&test->alen, sizeof(test->alen));
file.write((char*)&test->allocated, sizeof(test->allocated));
file.write((char*)&test->volume, sizeof(test->volume));
file.write((char*)test->abuf, test->alen);

now my resource file contains the uncompressed raw audio data, hence resulting in a large file.

If i could only find a way to compress the “abuf” 8-bit data, for instance, like remove silences? If anyone has any ideas to share, that would be greatly appreciated

Thanks

Karsten

Why don’t you just place the entire wav (or ogg, mp3, jpg, png etc.) into your resource file? You can read the file back out into memory and use SDL_RWops to load it.

http://kekkai.org/roger/sdl/rwops/rwops.html

Thanks for the link, but when trying a few things out, nothing writes to my resource file. Here is a code example :

SDL_RWops* rw(nullptr);

FILE* file = fopen(“nameoffile.bmp”, “r”);

rw = SDL_RWFromFP(file, 0);

fstream file2(“nameofresourcefile.000”, ios::binary | ios::out);
file2.write((char*)rw, ???);

The part with the ??? is where I get stuck, how can I determine the size of the image in memory? I figure I need to know the size of the chunk that rw is pointing to, but how? Before writing the image data to the resource file, I need this data size

I tried using fwrite, but the arguments for that function also require data size

Any ideas?

Thanks :slight_smile:

You can use ftell to tell you the size of the file when you open it. I don’t know C++, so this is the C code

FILE *infile = fopen(filename, "rb"); // Open the file

fseek(infile, 0L, SEEK_END); // Seek to the end of the file

long fileSize = ftell(infile); // Returns the current value of the position, i.e. how many bytes there are

Your code is exactly the same in C++, and I gave it a try. That part of the program works, however, when I write the data to file, the file remains to be 0KB large

For argument sake, I’ll use ur prev example and use this code :

FILE* outfile = fopen(filename, “wb”);
fwrite(rw, 1, fileSize, outfile);

I am stuck as to what exact arguments to put in the fwrite function.

  • rw is the pointer to the image data,
  • the second argument is the size of each data element to be written, i said 1 byte each,
  • size is the total size of all data, as aquired using ftell()
  • and outfile is the file we want to write to

After executing this, the resource file stays blank :frowning:

I’m not sure if you can use SDL_RWops to write to a file, I’ve always just read the file into memory and written it into the file directly:

// Open the file
FILE *infile = fopen(name, "rb");

// Seek to the end
fseek(fp, 0L, SEEK_END);

// Get the file size
long fileSize = ftell(fp);

// Seek back to the start
fseek(fp, 0L, SEEK_SET);

// Allocate a buffer large enough to hold the file in memory
char *buffer = malloc(fileSize * sizeof(char));

// Read the whole file into memory
fread(buffer, fileSize, 1, infile);

// Write the whole file into the resource file
fwrite(buffer, fileSize, 1, outfile);

// Free the memory afterwards
free(buffer);

// Close the infile afterwards
fclose(infile);

WOW! Thanks!!

So far this code works like magic!! I noticed that even though its my own resource file, i was still able to open the image in windows paint, so I added a small 1 byte data block at the start of the resource file so that no image editor can read it, do u do that too?

I presume from here onwards I load the resource data into memory and use RWops to load it into my relevant pointers?

Thanks again for your help, I really appreciate your time!!

BTW : Your game looks really good!

:slight_smile:

You can do it that way, just make sure when you read the file back in you skip the first byte, otherwise RWops will probably fail since it won’t recognise the file either!

This is really helpful, i have given all filetypes a try, so now i can use png, jpg, bmp, wav etc and it works beautifully.

I have been searching for a solution to this for a long time!

Thank you very much again for your help and patience, you are a legend!

K :smiley: