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!
#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
#include "Headers/Engine.hpp"
Engine::Engine()
{}
AudioManager & Engine::GetAudio()
{
return *audio;
}
void Engine::SetSound(AudioManager * sound)
{
this->audio = audio;
}
#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
#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);
}
#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
#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;
}
#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;
}