1 
2 #include <misc/sound_util.h>
3 
4 #include <FileClasses/FileManager.h>
5 #include <FileClasses/Vocfile.h>
6 
7 #include <misc/exceptions.h>
8 
9 #include <SDL_mixer.h>
10 #include <stdlib.h>
11 #include <memory.h>
12 
13 extern FileManager* pFileManager;
14 
concat2Chunks(Mix_Chunk * sound1,Mix_Chunk * sound2)15 Mix_Chunk* concat2Chunks(Mix_Chunk* sound1, Mix_Chunk* sound2)
16 {
17     Mix_Chunk* returnChunk;
18     if((returnChunk = (Mix_Chunk*) SDL_malloc(sizeof(Mix_Chunk))) == nullptr) {
19         return nullptr;
20     }
21 
22     returnChunk->allocated = 1;
23     returnChunk->volume = sound1->volume;
24     returnChunk->alen = sound1->alen + sound2->alen;
25 
26     if((returnChunk->abuf = (Uint8 *)SDL_malloc(returnChunk->alen)) == nullptr) {
27         SDL_free(returnChunk);
28         return nullptr;
29     }
30 
31     memcpy(returnChunk->abuf, sound1->abuf, sound1->alen);
32     memcpy(returnChunk->abuf + sound1->alen, sound2->abuf, sound2->alen);
33 
34     return returnChunk;
35 }
36 
concat3Chunks(Mix_Chunk * sound1,Mix_Chunk * sound2,Mix_Chunk * sound3)37 Mix_Chunk* concat3Chunks(Mix_Chunk* sound1, Mix_Chunk* sound2, Mix_Chunk* sound3)
38 {
39     Mix_Chunk* returnChunk;
40     if((returnChunk = (Mix_Chunk*) SDL_malloc(sizeof(Mix_Chunk))) == nullptr) {
41         return nullptr;
42     }
43 
44     returnChunk->allocated = 1;
45     returnChunk->volume = sound1->volume;
46     returnChunk->alen = sound1->alen + sound2->alen + sound3->alen;
47 
48     if((returnChunk->abuf = (Uint8 *)SDL_malloc(returnChunk->alen)) == nullptr) {
49         SDL_free(returnChunk);
50         return nullptr;
51     }
52 
53     memcpy(returnChunk->abuf, sound1->abuf, sound1->alen);
54     memcpy(returnChunk->abuf + sound1->alen, sound2->abuf, sound2->alen);
55     memcpy(returnChunk->abuf + sound1->alen + sound2->alen, sound3->abuf, sound3->alen);
56 
57     return returnChunk;
58 }
59 
concat4Chunks(Mix_Chunk * sound1,Mix_Chunk * sound2,Mix_Chunk * sound3,Mix_Chunk * sound4)60 Mix_Chunk* concat4Chunks(Mix_Chunk* sound1, Mix_Chunk* sound2, Mix_Chunk* sound3, Mix_Chunk* sound4)
61 {
62     Mix_Chunk* returnChunk;
63     if((returnChunk = (Mix_Chunk*) SDL_malloc(sizeof(Mix_Chunk))) == nullptr) {
64         return nullptr;
65     }
66 
67     returnChunk->allocated = 1;
68     returnChunk->volume = sound1->volume;
69     returnChunk->alen = sound1->alen + sound2->alen + sound3->alen + sound4->alen;
70 
71     if((returnChunk->abuf = (Uint8 *)SDL_malloc(returnChunk->alen)) == nullptr) {
72         SDL_free(returnChunk);
73         return nullptr;
74     }
75 
76     memcpy(returnChunk->abuf, sound1->abuf, sound1->alen);
77     memcpy(returnChunk->abuf + sound1->alen, sound2->abuf, sound2->alen);
78     memcpy(returnChunk->abuf + sound1->alen + sound2->alen, sound3->abuf, sound3->alen);
79     memcpy(returnChunk->abuf + sound1->alen + sound2->alen + sound3->alen, sound4->abuf, sound4->alen);
80 
81     return returnChunk;
82 }
83 
createEmptyChunk()84 Mix_Chunk* createEmptyChunk()
85 {
86     Mix_Chunk* returnChunk;
87     if((returnChunk = (Mix_Chunk*) SDL_malloc(sizeof(Mix_Chunk))) == nullptr) {
88         return nullptr;
89     }
90 
91     returnChunk->allocated = 1;
92     returnChunk->volume = 0;
93     returnChunk->alen = 0;
94     returnChunk->abuf = nullptr;
95 
96     return returnChunk;
97 }
98 
createSilenceChunk(int length)99 Mix_Chunk* createSilenceChunk(int length)
100 {
101     Mix_Chunk* returnChunk;
102     if((returnChunk = (Mix_Chunk*) SDL_malloc(sizeof(Mix_Chunk))) == nullptr) {
103         return nullptr;
104     }
105 
106     returnChunk->allocated = 1;
107     returnChunk->volume = MIX_MAX_VOLUME;
108     returnChunk->alen = length;
109 
110     if((returnChunk->abuf = (Uint8 *)SDL_calloc(returnChunk->alen,1)) == nullptr) {
111         SDL_free(returnChunk);
112         return nullptr;
113     }
114 
115     return returnChunk;
116 }
117 
getChunkFromFile(const std::string & filename)118 Mix_Chunk* getChunkFromFile(const std::string& filename) {
119     SDL_RWops* rwop = pFileManager->openFile(filename);
120 
121     Mix_Chunk* returnChunk;
122     if((returnChunk = LoadVOC_RW(rwop, 1)) == nullptr) {
123         THROW(io_error, "Cannot load '%s' !", filename);
124     }
125 
126     return returnChunk;
127 }
128 
getChunkFromFile(const std::string & filename,const std::string & alternativeFilename)129 Mix_Chunk* getChunkFromFile(const std::string& filename, const std::string& alternativeFilename) {
130     if(pFileManager->exists(filename)) {
131         return getChunkFromFile(filename);
132     } else if(pFileManager->exists(alternativeFilename)) {
133         return getChunkFromFile(alternativeFilename);
134     } else {
135         THROW(io_error, "Cannot open '%s' or '%s'!", filename, alternativeFilename);
136     }
137     return nullptr;
138 }
139