forked from KaiDrange/OctaChainer
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathotwriter.cpp
More file actions
executable file
·95 lines (85 loc) · 4.27 KB
/
Copy pathotwriter.cpp
File metadata and controls
executable file
·95 lines (85 loc) · 4.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include "otwriter.h"
const unsigned char header_bytes[] = {0x46,0x4F,0x52,0x4D,0x00,0x00,0x00,0x00,0x44,0x50,0x53,0x31,0x53,0x4D,0x50,0x41};
const unsigned char unknown_bytes[] = {0x00,0x00,0x00,0x00,0x00,0x02,0x00};
OTWriter::OTWriter(const QString fileName, const int sampleRate, const Loop_t loopSetting, const Stretch_t strechSetting, const TrigQuant_t trigQuantSetting, int gain, int tempo)
{
this->fileName = fileName;
std::fill_n((char*)&otData, sizeof(otData), 0);
memcpy(&otData, header_bytes, 16);
memcpy(&otData.unknown, unknown_bytes, 7);
this->tempo = tempo;
this->sampleRate = sampleRate;
this->gain = gain;
this->loopSetting = loopSetting;
this->stretchSetting = strechSetting;
this->trigQuantSetting = trigQuantSetting;
}
void OTWriter::updateData()
{
otData.tempo = SYSTEM_USE_LITTLE_ENDIAN ? __builtin_bswap32(tempo*6) : tempo*6;
// calculate bars from BPM, sampleRate and audioLength and round off to closest .25
int bars = ((tempo*totalSampleCount)/(sampleRate*60.0*4)) + 0.5;
bars *= 25;
otData.trimLen = SYSTEM_USE_LITTLE_ENDIAN ? __builtin_bswap32(bars) : bars;
otData.loopLen = SYSTEM_USE_LITTLE_ENDIAN ? __builtin_bswap32(bars) : bars;
otData.loop = SYSTEM_USE_LITTLE_ENDIAN ? __builtin_bswap32(loopSetting) : loopSetting;
otData.stretch = SYSTEM_USE_LITTLE_ENDIAN ? __builtin_bswap32(stretchSetting) : stretchSetting;
otData.quantize = trigQuantSetting;
otData.gain = SYSTEM_USE_LITTLE_ENDIAN ? __builtin_bswap16(gain + 48) : gain + 48;
if (tempSlices.count() > 1)
{
for (int i = 0; i < tempSlices.count(); i++)
{
otData.slices[i].startPoint = SYSTEM_USE_LITTLE_ENDIAN ? __builtin_bswap32(tempSlices[i].startPoint) : tempSlices[i].startPoint;
otData.slices[i].endPoint = SYSTEM_USE_LITTLE_ENDIAN ? __builtin_bswap32(tempSlices[i].endPoint) : tempSlices[i].endPoint;
otData.slices[i].loopPoint = SYSTEM_USE_LITTLE_ENDIAN ? __builtin_bswap32(tempSlices[i].loopPoint) : tempSlices[i].loopPoint;
}
otData.sliceCount = SYSTEM_USE_LITTLE_ENDIAN ? __builtin_bswap32(tempSlices.count()) : tempSlices.count();
}
else
otData.sliceCount = 0;
otData.trimEnd = SYSTEM_USE_LITTLE_ENDIAN ? __builtin_bswap32(totalSampleCount) : totalSampleCount;
setChecksum();
}
void OTWriter::write(uint32_t totalSamples)
{
this->totalSampleCount = totalSamples;
updateData();
QFile file(fileName);
file.open(QIODevice::WriteOnly);
//QDataStream outStream;
//outStream.setDevice(&file);
QDataStream outStream(&file);
outStream.writeRawData((char*)&otData.header, sizeof(otData.header));
outStream.writeRawData((char*)&otData.unknown, sizeof(otData.unknown));
outStream.writeRawData((char*)&otData.tempo, sizeof(otData.tempo));
outStream.writeRawData((char*)&otData.trimLen, sizeof(otData.trimLen));
outStream.writeRawData((char*)&otData.loopLen, sizeof(otData.loopLen));
outStream.writeRawData((char*)&otData.stretch, sizeof(otData.stretch));
outStream.writeRawData((char*)&otData.loop, sizeof(otData.loop));
outStream.writeRawData((char*)&otData.gain, sizeof(otData.gain));
outStream.writeRawData((char*)&otData.quantize, sizeof(otData.quantize));
outStream.writeRawData((char*)&otData.trimStart, sizeof(otData.trimStart));
outStream.writeRawData((char*)&otData.trimEnd, sizeof(otData.trimEnd));
outStream.writeRawData((char*)&otData.loopPoint, sizeof(otData.loopPoint));
outStream.writeRawData((char*)&otData.slices, sizeof(Slice)*64);
outStream.writeRawData((char*)&otData.sliceCount, sizeof(otData.sliceCount));
outStream.writeRawData((char*)&otData.checkSum, sizeof(otData.checkSum));
file.close();
}
void OTWriter::setChecksum()
{
uint16_t value = 0;
unsigned char* bytePos = reinterpret_cast<unsigned char*>(&otData);
for (int i = 16; i < sizeof(otData) - 2; i++)
value += bytePos[i];
otData.checkSum = SYSTEM_USE_LITTLE_ENDIAN ? __builtin_bswap16(value) : value;
}
void OTWriter::addSlice(uint32_t start, uint32_t end)
{
Slice slice;
slice.loopPoint = 0xFFFFFFFF;
slice.startPoint = start;
slice.endPoint = end;
this->tempSlices.append(slice);
}