23 bool ok =
file.loadFileAsData(contents);
27 sound_->addError(
"Couldn't read \"" +
file.getFullPathName() +
"\"");
31 read(
static_cast<const char *
>(contents.
getData()),
static_cast<int>(contents.
getSize()));
43 Region *buildingRegion =
nullptr;
44 bool inComment =
false;
45 bool inControl =
false;
55 if ((
c !=
' ') && (
c !=
'\t'))
87 if ((
c ==
'\n') || (
c ==
'\r'))
99 if ((
c ==
'\r') || (
c ==
'\n'))
114 const char *tagStart =
p;
118 if ((
c ==
'\n') || (
c ==
'\r'))
120 error(
"Unterminated tag");
130 error(
"Unterminated tag");
137 buildingRegion = &curGlobal;
141 else if (tag ==
"region")
143 if (buildingRegion && (buildingRegion == &curRegion))
147 curRegion = curGroup;
148 buildingRegion = &curRegion;
152 else if (tag ==
"group")
154 if (buildingRegion && (buildingRegion == &curRegion))
160 curGroup = curGlobal;
161 buildingRegion = &curGroup;
166 else if (tag ==
"control")
168 if (buildingRegion && (buildingRegion == &curRegion))
173 buildingRegion =
nullptr;
178 error(
"Illegal tag");
202 if ((
c ==
'\r') || (
c ==
'\n'))
214 const char *parameterStart =
p;
218 if ((
c ==
'=') || (
c ==
' ') || (
c ==
'\t') || (
c ==
'\r') || (
c ==
'\n'))
223 if ((
p >= end) || (
c !=
'='))
225 error(
"Malformed parameter");
231 if (
opcode ==
"default_path")
237 const char *valueStart =
p;
241 if ((
c ==
' ') || (
c ==
'\t') || (
c ==
'\n') || (
c ==
'\r'))
249 sound_->addUnsupportedOpcode(fauxOpcode);
252 else if (
opcode ==
"sample")
260 buildingRegion->
sample =
sound_->addSample(path, defaultPath);
264 error(
"Adding sample outside a group or region");
269 error(
"Empty sample path");
274 const char *valueStart =
p;
278 if ((
c ==
' ') || (
c ==
'\t') || (
c ==
'\n') || (
c ==
'\r'))
285 if (buildingRegion ==
nullptr)
287 error(
"Setting a parameter outside a region or group");
289 else if (
opcode ==
"lokey")
293 else if (
opcode ==
"hikey")
301 else if (
opcode ==
"lovel")
305 else if (
opcode ==
"hivel")
309 else if (
opcode ==
"trigger")
313 else if (
opcode ==
"group")
315 buildingRegion->
group =
static_cast<int>(
value.getLargeIntValue());
321 else if (
opcode ==
"offset")
334 buildingRegion->
end = end2;
339 bool modeIsSupported =
value ==
"no_loop" ||
value ==
"one_shot" ||
value ==
"loop_continuous";
347 sound_->addUnsupportedOpcode(fauxOpcode);
350 else if (
opcode ==
"loop_start" ||
opcode ==
"loopstart")
358 else if (
opcode ==
"transpose")
362 else if (
opcode ==
"tune")
364 buildingRegion->
tune =
value.getIntValue();
366 else if (
opcode ==
"pitch_keycenter")
370 else if (
opcode ==
"pitch_keytrack")
382 else if (
opcode ==
"volume")
388 buildingRegion->
pan =
value.getFloatValue();
390 else if (
opcode ==
"amp_veltrack")
394 else if (
opcode ==
"ampeg_delay")
398 else if (
opcode ==
"ampeg_start")
402 else if (
opcode ==
"ampeg_attack")
406 else if (
opcode ==
"ampeg_hold")
410 else if (
opcode ==
"ampeg_decay")
414 else if (
opcode ==
"ampeg_sustain")
418 else if (
opcode ==
"ampeg_release")
422 else if (
opcode ==
"ampeg_vel2delay")
426 else if (
opcode ==
"ampeg_vel2attack")
430 else if (
opcode ==
"ampeg_vel2hold")
434 else if (
opcode ==
"ampeg_vel2decay")
438 else if (
opcode ==
"ampeg_vel2sustain")
442 else if (
opcode ==
"ampeg_vel2release")
446 else if (
opcode ==
"default_path")
448 error(
"\"default_path\" outside of <control> tag");
463 if ((
c !=
' ') && (
c !=
'\t'))
469 if ((
c ==
'\r') || (
c ==
'\n'))
478 if (buildingRegion && (buildingRegion == &curRegion))
487 char lineEndChar = *
p++;
489 if ((lineEndChar ==
'\r') && (*
p ==
'\n'))
501 const char *end = endIn;
502 const char *pathStart =
p;
503 const char *potentialEnd =
nullptr;
515 while (
p < end && *
p ==
' ')
520 else if ((
c ==
'\n') || (
c ==
'\r') || (
c ==
'\t'))
551 const char*
const chars = str.
toRawUTF8();
555 if ((
c >=
'0') && (
c <=
'9'))
561 static const int notes[] = {
562 12 + 0, 12 + 2, 3, 5, 7, 8, 10,
564 if ((
c >=
'A') && (
c <=
'G'))
566 note = notes[
c -
'A'];
568 else if ((
c >=
'a') && (
c <=
'g'))
570 note = notes[
c -
'a'];
575 if ((
c ==
'b') || (
c ==
'#'))
590 int result = octave * 12 + note + (57 - 4 * 12);
596 if (str ==
"release")
613 if (str ==
"no_loop")
617 if (str ==
"one_shot")
621 if (str ==
"loop_continuous")
625 if (str ==
"loop_sustain")
636 *newRegion = *region;
637 sound_->addRegion(newRegion);
645 sound_->addError(fullMessage);
opcode
Definition Spc_Cpu.h:173
static void message(int level, const char *fmt,...)
Definition adplugdb.cpp:120
void finishRegion(Region *region)
Definition SFZReader.cpp:632
int keyValue(const water::String &str)
Definition SFZReader.cpp:549
const char * handleLineEnd(const char *p)
Definition SFZReader.cpp:484
void read(const water::File &file)
Definition SFZReader.cpp:20
int line_
Definition SFZReader.h:39
int triggerValue(const water::String &str)
Definition SFZReader.cpp:594
void error(const water::String &message)
Definition SFZReader.cpp:640
~Reader()
Definition SFZReader.cpp:18
int loopModeValue(const water::String &str)
Definition SFZReader.cpp:611
Reader(Sound *sound)
Definition SFZReader.cpp:16
Sound * sound_
Definition SFZReader.h:38
const char * readPathInto(water::String *pathOut, const char *p, const char *end)
Definition SFZReader.cpp:497
Definition SFZReader.h:45
Definition CharPointer_UTF8.h:45
Definition MemoryBlock.h:39
size_t getSize() const noexcept
Definition MemoryBlock.h:102
void * getData() const noexcept
Definition MemoryBlock.h:91
String substring(int startIndex, int endIndex) const
Definition String.cpp:1373
const char * toRawUTF8() const
Definition String.cpp:1925
int getIntValue() const noexcept
Definition String.cpp:1781
bool isEmpty() const noexcept
Definition String.h:238
static PuglViewHint int value
Definition pugl.h:1708
Definition SFZDebug.cpp:11
unsigned long long uint64
Definition water.h:102
long long int64
Definition water.h:100
png_uint_32 length
Definition png.c:2247
float release
Definition SFZRegion.h:23
float hold
Definition SFZRegion.h:23
float delay
Definition SFZRegion.h:23
float sustain
Definition SFZRegion.h:23
float attack
Definition SFZRegion.h:23
float decay
Definition SFZRegion.h:23
float start
Definition SFZRegion.h:23
Definition SFZRegion.h:30
float amp_veltrack
Definition SFZRegion.h:83
int lokey
Definition SFZRegion.h:65
Sample * sample
Definition SFZRegion.h:64
int group
Definition SFZRegion.h:68
EGParameters ampeg_veltrack
Definition SFZRegion.h:85
Trigger trigger
Definition SFZRegion.h:67
EGParameters ampeg
Definition SFZRegion.h:85
water::int64 offset
Definition SFZRegion.h:72
float pan
Definition SFZRegion.h:82
int tune
Definition SFZRegion.h:78
int pitch_keycenter
Definition SFZRegion.h:79
bool negative_end
Definition SFZRegion.h:74
water::int64 off_by
Definition SFZRegion.h:69
water::int64 end
Definition SFZRegion.h:73
int bend_down
Definition SFZRegion.h:80
void clear()
Definition SFZRegion.cpp:33
int pitch_keytrack
Definition SFZRegion.h:79
int bend_up
Definition SFZRegion.h:80
water::int64 loop_end
Definition SFZRegion.h:76
int hivel
Definition SFZRegion.h:66
int hikey
Definition SFZRegion.h:65
LoopMode loop_mode
Definition SFZRegion.h:75
Trigger
Definition SFZRegion.h:32
@ legato
Definition SFZRegion.h:36
@ release
Definition SFZRegion.h:34
@ first
Definition SFZRegion.h:35
@ attack
Definition SFZRegion.h:33
LoopMode
Definition SFZRegion.h:40
@ no_loop
Definition SFZRegion.h:42
@ sample_loop
Definition SFZRegion.h:41
@ loop_sustain
Definition SFZRegion.h:45
@ one_shot
Definition SFZRegion.h:43
@ loop_continuous
Definition SFZRegion.h:44
int transpose
Definition SFZRegion.h:77
float volume
Definition SFZRegion.h:82
water::int64 loop_start
Definition SFZRegion.h:76
int lovel
Definition SFZRegion.h:66
const char * text
Definition swell-functions.h:167
uch * p
Definition crypt.c:594
return c
Definition crypt.c:175
int result
Definition process.c:1455
struct zdirent * file
Definition win32.c:1500