Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Need help with an audio manager using a DAT file  (Read 2132 times)

0 Members and 1 Guest are viewing this topic.

AdventWolf

  • Jr. Member
  • **
  • Posts: 54
    • View Profile
Need help with an audio manager using a DAT file
« on: January 05, 2011, 02:43:07 am »
I'm using the tutorial on storing your files inside a .DAT file.
The problem is inside this function, the program just freezes.
char* AudioDAT::GetAudio (std::string filename)

If I comment out this part: if (m_buffer != NULL){}
then the debugger points to the next part of the function to be the problem.

Any tips are appreciated!

Code: [Select]

#ifndef ENGINE_HPP_
#define ENGINE_HPP_

class AudioManager;

#define SYSTEM Engine::SYSTEM
#define AUDIO  SYSTEM.GetAudio()

#include <SFML/Audio.hpp>

class Engine
{
AudioManager  * audio;

public:
Engine();
static Engine SYSTEM;
AudioManager  & GetAudio();
void SetSound(AudioManager  * audio);
};
#endif


Code: [Select]
#include "Headers/Engine.hpp"

Engine::Engine()
{}

AudioManager & Engine::GetAudio()
{
return *audio;
}

void Engine::SetSound(AudioManager * sound)
{
this->audio = audio;
}


Code: [Select]
#ifndef AUDIO_DAT_H
#define AUDIO_DAT_H

#include <iostream>
#include <vector>
#include <fstream>
#include <string>

struct sAudioDATHeader
{
    char uniqueID[5]; /// Unique ID used to know if this file is a DAT File from this class
    char version[3]; /// Version of the DAT file format
    unsigned int nb_files; /// Number of files in the DAT file
};

struct sAudioEntry
{
    char name[300]; /// Name of the data file
    long size; /// Size of the data file
    long offset; /// Offset, in the DAT file where the file is
};

class AudioDAT
{
private :
    std::string m_datfile; /// name of the DAT file
    sAudioDATHeader m_header; /// file header
    std::vector<sAudioEntry> m_entries; /// vector of files entries
    char* m_buffer; /// Buffer pointing on a file in memory
public :
    AudioDAT (void);
    ~AudioDAT (void);
    bool Create (std::vector<std::string> files, std::string destination);
    void Read (std::string source);
    char* GetAudio (std::string filename);
    long int GetAudioSize (std::string filename);
};

#endif


Code: [Select]
#include "Headers/AudioDAT.hpp"

AudioDAT::AudioDAT (void)
{
    m_buffer = NULL;
}
 
AudioDAT::~AudioDAT (void)
{
    if (m_buffer!=NULL)
        delete (m_buffer);
}

bool AudioDAT::Create (std::vector<std::string> files, std::string destination)
{
    //A file entry in order to push it in the object's std::vector
    sAudioEntry entry;
    //An input file stream to read each file included
    std::ifstream file;
    //An output file stream to write our DAT file
    std::ofstream datfile;
    //The buffer used to read/write the DAT file
    char buffer[1];
 
    //DATHeader
    //We start by filling it with 0
    memset (&m_header, 0, sizeof(m_header));
    //Then we copy the ID
    memcpy (m_header.uniqueID, "IMGDAT", 5);
    //Then the version
    memcpy (m_header.version, "0.1", 3);
    //Then the number of files to include
    m_header.nb_files = files.size();
 
    //Next, we open each file in orderto create the File Entries Table
    for (unsigned int i = 0; i<files.size(); i++)
    {
        file.open (files[i].c_str(), std::ifstream::in | std::ifstream::binary);
        if (file.is_open())
        {
            //Filling the FileEntry with 0
            memset (&entry, 0, sizeof(sAudioEntry) );
            //We keep the file name
            memcpy (entry.name, files[i].c_str(), strlen ( files[i].c_str() ) );
            //We calculate its size
            file.seekg (0, std::ios::end);
            entry.size = file.tellg();
            //Since we don't know exactly its final position in the DAT file, let's use 0
            entry.offset = 0;
            //We finished with this file
            file.close();
 
            //Finally, we add this File Entry in our std::vector
            m_entries.push_back(entry);
        }
        else
        {
            //Simple error track
            std::cout<<"File "<<files[i]<<" raise an error."<<std::endl;
            return (false);
        }
    }
 
    //Now, we know everything about our files, we can update offsets
    long actual_offset = 0;
    actual_offset += sizeof(sAudioDATHeader);
    actual_offset += m_header.nb_files * sizeof(sAudioEntry);
    for (unsigned int i=0;i<m_entries.size();i++)
    {
        m_entries[i].offset = actual_offset;
        actual_offset += m_entries[i].size;
    }
 
    //And finally, we are writing the DAT file
    datfile.open (destination.c_str(), std::ofstream::out | std::ofstream::binary);
 
    //First, we write the header
    datfile.write ((char*)&m_header, sizeof(sAudioDATHeader) );
 
    //Then, the File Entries Table
    for (unsigned int i=0;i<m_entries.size();i++)
    {
        datfile.write ((char*)&m_entries[i], sizeof(sAudioEntry) );
    }
 
    //Finally, we write each file
    for (unsigned int i = 0; i<m_entries.size(); i++)
    {
        file.open (m_entries[i].name, std::ifstream::in | std::ifstream::binary);
        if (file.is_open())
        {
            file.seekg (0, std::ios::beg);
            while (file.read (buffer, 1))
            {
                datfile.write (buffer, 1);
            }
            file.close();
        }
        file.clear();
    }
    //And it's finished
    datfile.close();
    return (true);
}

void AudioDAT::Read (std::string source)
{
    //The input file stream from which we want informations
    std::ifstream datfile;
    //A file entry in order to push it in the object's std::vector
    sAudioEntry entry;
 
    //Filling the header with 0
    memset (&m_header, 0, sizeof(m_header));
    //We open the DAT file to read it
    datfile.open (source.c_str(), std::ifstream::in | std::ifstream::binary);
    if (datfile.is_open())
    {
        //Getting to the Header position
        datfile.seekg (0, std::ios::beg);
        //Reading the DAT Header
        datfile.read ((char*)&m_header, sizeof(sAudioDATHeader));
        //Next we are reading each file entry
        for (unsigned int i=0;i<m_header.nb_files;i++)
        {
            //Reading a File Entry
            datfile.read ((char*)&entry, sizeof(sAudioEntry));
            //Pushing it in our std::vector
            m_entries.push_back(entry);
        }
        //Since all seems ok, we keep the DAT file name
        m_datfile = source;
    }
    //Closing the DAT file
    datfile.close();
}

char* AudioDAT::GetAudio (std::string filename) //The PROBLEM STARTS HERE
{
    //The input file stream from which we want information
    std::ifstream datfile;
 
    //Cleaning properly an ancient file loaded
    if (m_buffer != NULL) //The Program freezes here
    {
        delete (m_buffer);
        m_buffer = NULL;
    }
 
    //First, we have to find the file needed
    for (unsigned int i=0; i<m_header.nb_files;i++)
    {
        //If we found it
        if (m_entries[i].name == filename)
        {
            //We are allocating memory to the buffer
            m_buffer = new char[(m_entries[i].size)];
            //Simple error catch
            if (m_buffer==NULL)
                return (NULL);
            //Opening the DAT file ot read the file datas needed
            datfile.open (m_datfile.c_str(), std::ifstream::in | std::ifstream::binary);
            if (datfile.is_open())
            {
                //Going to the right position
                datfile.seekg (m_entries[i].offset, std::ios::beg);
                //Reading
                datfile.read (m_buffer, m_entries[i].size);
                //We can close the DAT file
                datfile.close();
                //Returning the buffer
                return (m_buffer);
            }
        }
    }
    //Finally, there is no such file in our DAT file
    return (NULL);
}

long int AudioDAT::GetAudioSize (std::string filename)
{
    //First, we have to find the file needed
    for (unsigned int i=0; i<m_header.nb_files;i++)
    {
        //If we found it
        if (m_entries[i].name == filename)
        {
            //Returning the size of the file found
            return (m_entries[i].size);
        }
    }
    return (0);
}


Code: [Select]
#ifndef AUDIO_MANAGER_H
#define AUDIO_MANAGER_H

#include <map>
#include <vector>
#include <string>
#include "Headers/Engine.hpp"
#include "Headers/AudioDAT.hpp"

class AudioManager
{
std::vector<std::string> audio_container;
std::map<std::string, sf::Music> static_audio_map;
AudioDAT data;

public:
AudioManager();
const sf::Music & GetAudio(sf::Music & temp, std::string audio_id);
};

#endif


Code: [Select]
#include "Headers/AudioManager.hpp"
#include <iostream>

AudioManager::AudioManager()
{
//Create DAT file and Load Audio
audio_container.push_back("Test.ogg");

if(!data.Create(audio_container,"AUD.dat"))
{
std::cout << "Could not create AUD.dat" << std::endl;
}

data.Read("AUD.dat");
}

const sf::Music & AudioManager::GetAudio(sf::Music & temp, std::string audio_id)
{
char * temp_data = data.GetAudio(audio_id);// The Program freezes inside this function
if(temp_data == NULL)
{
std::cout << "Error Loading Audio: " << audio_id << std::endl;
exit(EXIT_FAILURE);
}

temp.OpenFromMemory(temp_data, data.GetAudioSize(audio_id));
return temp;
}


Code: [Select]
#include "Headers/Engine.hpp"
#include "Headers/AudioManager.hpp"

Engine SYSTEM;

int main()
{
sf::Music test;
AudioManager audio;

AUDIO.GetAudio(test,"test.ogg");
        test.Play();

while(true)
{
}
return 0;
}