// This example will show how to override file access with irrKlang. // This is useful if you want to read sounds from other sources than // just files, for example from custom internet streams or // an own encypted archive format. // lets start: include irrKlang headers and other input/output stuff // needed to print and get user input from the console. #if defined(WIN32) #include #else #include "../common/conio.h" #endif #include #include #include using namespace irrklang; #pragma comment(lib, "irrKlang.lib") // link with irrKlang.dll // To start, we need to implement the class IFileFactory, which irrKlang uses // to open files. The interface consists only of one single method named // createFileReader(const ik_c8* filename). In this method, we create return // our own file access class and return it: // a class implementing the IFileFactory interface to override irrklang file access class CMyFileFactory : public IFileFactory { public: //! Opens a file for read access. Simply return 0 if file not found. virtual IFileReader* createFileReader(const ik_c8* filename) { printf("MyFileFactory: open file %s\n", filename); FILE* file = fopen(filename, "rb"); if (!file) return 0; return new CMyReadFile(file, filename); } protected: // To write our own file access methods returned in the method above, // we only need to implement the IFileReader interface, which has some // standard methods like read(), seek(), getPos() etc. In this example // we simply use fopen, fread, fseek etc and print to the console // when we are reading or seeking: // an own implementation of IReadFile to overwrite read access to files class CMyReadFile : public IFileReader { public: // constructor, store size of file and filename CMyReadFile(FILE* openedFile, const ik_c8* filename) { File = openedFile; strcpy(Filename, filename); // get file size fseek(File, 0, SEEK_END); FileSize = ftell(File); fseek(File, 0, SEEK_SET); } ~CMyReadFile() { fclose(File); } //! reads data, returns how much was read ik_s32 read(void* buffer, ik_u32 sizeToRead) { printf("CMyReadFile: read %d bytes\n", sizeToRead); return (ik_s32)fread(buffer, 1, sizeToRead, File); } //! changes position in file, returns true if successful bool seek(ik_s32 finalPos, bool relativeMovement) { printf("CMyReadFile: seek to position %d\n", finalPos); return fseek(File, finalPos, relativeMovement ? SEEK_CUR : SEEK_SET) == 0; } //! returns size of file ik_s32 getSize() { return FileSize; } //! returns where in the file we are. ik_s32 getPos() { return ftell(File); } //! returns name of file const ik_c8* getFileName() { return Filename; } FILE* File; char Filename[1024]; ik_s32 FileSize; }; // end class CMyReadFile }; // end class CMyFileFactory // The main work is done, the only thing missing is to start up the // sound engine and tell it to use the created FileFactory for file access: // irrKlang 3D sound engine example 04, // demonstrating how to override file access of irrKlang int main(int argc, const char** argv) { // start the sound engine with default parameters ISoundEngine* engine = createIrrKlangDevice(); if (!engine) return 0; // error starting up the engine // create an instance of the file factory and let // irrKlang know about it. irrKlang will drop() the // factory itself if it doesn't need it any longer. CMyFileFactory* factory = new CMyFileFactory(); engine->addFileFactory(factory); factory->drop(); // we don't need it anymore, delete it // that's it, play some sounds with our overriden // file access methods: printf("\nDemonstrating file access overriding.\n"); printf("Press any key to start playing sounds, then press escape to cancel\n"); getch(); engine->play2D("../../media/getout.ogg", true); while(true) // endless loop until user exits { // play some wave sound engine->play2D("../../media/explosion.wav"); if (getch() == 27) break; // user pressed ESCAPE key, cancel } engine->drop(); // delete engine return 0; }