1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 /*
23  * VGMTrans (c) 2002-2019
24  * Licensed under the zlib license,
25  * refer to the included VGMTrans_LICENSE.txt file
26  */
27 
28 #include "audio/soundfont/common.h"
29 #include "audio/soundfont/vgmitem.h"
30 #include "audio/soundfont/vgminstrset.h"
31 
32 using namespace std;
33 
VGMItem()34 VGMItem::VGMItem() : _dwOffset(0), _unLength(0), _vgmfile(nullptr) {}
35 
VGMItem(VGMFile * thevgmfile,uint32 theOffset,uint32 theLength,const Common::String theName)36 VGMItem::VGMItem(VGMFile *thevgmfile, uint32 theOffset, uint32 theLength, const Common::String theName)
37 		: _vgmfile(thevgmfile),
38 		  _name(theName),
39 		  _dwOffset(theOffset),
40 		  _unLength(theLength) {}
41 
~VGMItem()42 VGMItem::~VGMItem() {}
43 
GetRawFile()44 RawFile *VGMItem::GetRawFile() {
45 	return _vgmfile->_rawfile;
46 }
47 
GetBytes(uint32 nIndex,uint32 nCount,void * pBuffer)48 uint32 VGMItem::GetBytes(uint32 nIndex, uint32 nCount, void *pBuffer) {
49 	return _vgmfile->GetBytes(nIndex, nCount, pBuffer);
50 }
51 
GetByte(uint32 offset)52 uint8 VGMItem::GetByte(uint32 offset) {
53 	return _vgmfile->GetByte(offset);
54 }
55 
GetShort(uint32 offset)56 uint16 VGMItem::GetShort(uint32 offset) {
57 	return _vgmfile->GetShort(offset);
58 }
59 
60 //  ****************
61 //  VGMContainerItem
62 //  ****************
63 
VGMContainerItem()64 VGMContainerItem::VGMContainerItem() : VGMItem() {
65 	AddContainer(_headers);
66 	AddContainer(_localitems);
67 }
68 
VGMContainerItem(VGMFile * thevgmfile,uint32 theOffset,uint32 theLength,const Common::String theName)69 VGMContainerItem::VGMContainerItem(VGMFile *thevgmfile, uint32 theOffset, uint32 theLength,
70 								   const Common::String theName)
71 		: VGMItem(thevgmfile, theOffset, theLength, theName) {
72 	AddContainer(_headers);
73 	AddContainer(_localitems);
74 }
75 
~VGMContainerItem()76 VGMContainerItem::~VGMContainerItem() {
77 	DeleteVect(_headers);
78 	DeleteVect(_localitems);
79 }
80 
AddHeader(uint32 offset,uint32 length,const Common::String & name)81 VGMHeader *VGMContainerItem::AddHeader(uint32 offset, uint32 length, const Common::String &name) {
82 	VGMHeader *header = new VGMHeader(this, offset, length, name);
83 	_headers.push_back(header);
84 	return header;
85 }
86 
AddSimpleItem(uint32 offset,uint32 length,const Common::String & name)87 void VGMContainerItem::AddSimpleItem(uint32 offset, uint32 length, const Common::String &name) {
88 	_localitems.push_back(new VGMItem(this->_vgmfile, offset, length, name));
89 }
90 
91 // *********
92 // VGMFile
93 // *********
94 
VGMFile(RawFile * theRawFile,uint32 offset,uint32 length,Common::String theName)95 VGMFile::VGMFile(RawFile *theRawFile, uint32 offset,
96 				 uint32 length, Common::String theName)
97 		: VGMContainerItem(this, offset, length, theName),
98 		  _rawfile(theRawFile) {}
99 
~VGMFile(void)100 VGMFile::~VGMFile(void) {}
101 
LoadVGMFile()102 bool VGMFile::LoadVGMFile() {
103 	bool val = Load();
104 	if (!val)
105 		return false;
106 
107 	return val;
108 }
109 
110 // These functions are common to all VGMItems, but no reason to refer to vgmfile
111 // or call GetRawFile() if the item itself is a VGMFile
GetRawFile()112 RawFile *VGMFile::GetRawFile() {
113 	return _rawfile;
114 }
115 
GetBytes(uint32 nIndex,uint32 nCount,void * pBuffer)116 uint32 VGMFile::GetBytes(uint32 nIndex, uint32 nCount, void *pBuffer) {
117 	// if unLength != 0, verify that we're within the bounds of the file, and truncate num read
118 	// bytes to end of file
119 	if (_unLength != 0) {
120 		uint32 endOff = _dwOffset + _unLength;
121 		assert(nIndex >= _dwOffset && nIndex < endOff);
122 		if (nIndex + nCount > endOff)
123 			nCount = endOff - nIndex;
124 	}
125 
126 	return _rawfile->GetBytes(nIndex, nCount, pBuffer);
127 }
128 
129 // *********
130 // VGMHeader
131 // *********
132 
VGMHeader(VGMItem * parItem,uint32 offset,uint32 length,const Common::String & name)133 VGMHeader::VGMHeader(VGMItem *parItem, uint32 offset, uint32 length, const Common::String &name)
134 		: VGMContainerItem(parItem->_vgmfile, offset, length, name) {}
135 
~VGMHeader()136 VGMHeader::~VGMHeader() {}
137 
138 // ******
139 // VGMRgn
140 // ******
141 
VGMRgn(VGMInstr * instr,uint32 offset,uint32 length,Common::String name)142 VGMRgn::VGMRgn(VGMInstr *instr, uint32 offset, uint32 length, Common::String name)
143 		: VGMContainerItem(instr->_parInstrSet, offset, length, name),
144 		  _keyLow(0),
145 		  _keyHigh(127),
146 		  _velLow(0),
147 		  _velHigh(127),
148 		  _unityKey(-1),
149 		  _fineTune(0),
150 		  _sampNum(0),
151 		  _sampCollPtr(nullptr),
152 		  _volume(-1),
153 		  _pan(0.5),
154 		  _attack_time(0),
155 		  _decay_time(0),
156 		  _release_time(0),
157 		  _sustain_level(-1),
158 		  _sustain_time(0),
159 		  _attack_transform(no_transform),
160 		  _release_transform(no_transform),
161 		  _parInstr(instr) {
162 	AddContainer<VGMRgnItem>(_items);
163 }
164 
~VGMRgn()165 VGMRgn::~VGMRgn() {
166 	DeleteVect<VGMRgnItem>(_items);
167 }
168 
SetPan(uint8 p)169 void VGMRgn::SetPan(uint8 p) {
170 	if (p == 127) {
171 		_pan = 1.0;
172 	} else if (p == 0) {
173 		_pan = 0;
174 	} else if (p == 64) {
175 		_pan = 0.5;
176 	} else {
177 		_pan = _pan / 127.0;
178 	}
179 }
180 
AddGeneralItem(uint32 offset,uint32 length,const Common::String & name)181 void VGMRgn::AddGeneralItem(uint32 offset, uint32 length, const Common::String &name) {
182 	_items.push_back(new VGMRgnItem(this, VGMRgnItem::RIT_GENERIC, offset, length, name));
183 }
184 
185 // assumes pan is given as 0-127 value, converts it to our double -1.0 to 1.0 format
AddPan(uint8 p,uint32 offset,uint32 length)186 void VGMRgn::AddPan(uint8 p, uint32 offset, uint32 length) {
187 	SetPan(p);
188 	_items.push_back(new VGMRgnItem(this, VGMRgnItem::RIT_PAN, offset, length, "Pan"));
189 }
190 
AddVolume(double vol,uint32 offset,uint32 length)191 void VGMRgn::AddVolume(double vol, uint32 offset, uint32 length) {
192 	_volume = vol;
193 	_items.push_back(new VGMRgnItem(this, VGMRgnItem::RIT_VOL, offset, length, "Volume"));
194 }
195 
AddUnityKey(int8 uk,uint32 offset,uint32 length)196 void VGMRgn::AddUnityKey(int8 uk, uint32 offset, uint32 length) {
197 	this->_unityKey = uk;
198 	_items.push_back(new VGMRgnItem(this, VGMRgnItem::RIT_UNITYKEY, offset, length, "Unity Key"));
199 }
200 
AddKeyLow(uint8 kl,uint32 offset,uint32 length)201 void VGMRgn::AddKeyLow(uint8 kl, uint32 offset, uint32 length) {
202 	_keyLow = kl;
203 	_items.push_back(
204 			new VGMRgnItem(this, VGMRgnItem::RIT_KEYLOW, offset, length, "Note Range: Low Key"));
205 }
206 
AddKeyHigh(uint8 kh,uint32 offset,uint32 length)207 void VGMRgn::AddKeyHigh(uint8 kh, uint32 offset, uint32 length) {
208 	_keyHigh = kh;
209 	_items.push_back(
210 			new VGMRgnItem(this, VGMRgnItem::RIT_KEYHIGH, offset, length, "Note Range: High Key"));
211 }
212 
AddSampNum(int sn,uint32 offset,uint32 length)213 void VGMRgn::AddSampNum(int sn, uint32 offset, uint32 length) {
214 	_sampNum = sn;
215 	_items.push_back(new VGMRgnItem(this, VGMRgnItem::RIT_SAMPNUM, offset, length, "Sample Number"));
216 }
217 
218 // **********
219 // VGMRgnItem
220 // **********
221 
VGMRgnItem(VGMRgn * rgn,RgnItemType theType,uint32 offset,uint32 length,const Common::String & name)222 VGMRgnItem::VGMRgnItem(VGMRgn *rgn, RgnItemType theType, uint32 offset, uint32 length,
223 					   const Common::String &name)
224 		: VGMItem(rgn->_vgmfile, offset, length, name), _type(theType) {}
225