sample formats, threshold for saving as s16, slightly more "correct" playback output
parent
cbce51744c
commit
0a14aec9e5
10
notes
10
notes
|
@ -35,14 +35,14 @@ TODO {
|
||||||
about-license info
|
about-license info
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fix overrun-by-1 on sample preview
|
||||||
|
|
||||||
|
templatize svfilter and have mono version for synth use
|
||||||
|
|
||||||
revert-to-saved menu action
|
revert-to-saved menu action
|
||||||
|
|
||||||
- splice-between behavior when trying to hook up a command input to something with both a command input and output while already connected
|
|
||||||
|
|
||||||
distortion effect
|
distortion effect
|
||||||
|
|
||||||
uh... maybe save/load samples as s16 instead of f32
|
|
||||||
|
|
||||||
automation node {
|
automation node {
|
||||||
listens for one specific param
|
listens for one specific param
|
||||||
supports tweening
|
supports tweening
|
||||||
|
@ -58,6 +58,8 @@ TODO {
|
||||||
editing song info should probably be an UndoStack action
|
editing song info should probably be an UndoStack action
|
||||||
editing song *tempo* ABSOLUTELY should
|
editing song *tempo* ABSOLUTELY should
|
||||||
|
|
||||||
|
maybe retool rendering to feed f32 (or even f64) to ffmpeg
|
||||||
|
|
||||||
figure out what to actually do with directory config
|
figure out what to actually do with directory config
|
||||||
|
|
||||||
buffer helper akin to what quicklevel does {
|
buffer helper akin to what quicklevel does {
|
||||||
|
|
|
@ -406,8 +406,8 @@ qint64 AudioEngine::readData(char *data, qint64 maxlen) {
|
||||||
// convert non-interleaved floating point into interleaved int16
|
// convert non-interleaved floating point into interleaved int16
|
||||||
int16_t* l = reinterpret_cast<int16_t*>(data);
|
int16_t* l = reinterpret_cast<int16_t*>(data);
|
||||||
int16_t* r = reinterpret_cast<int16_t*>(data+smp);
|
int16_t* r = reinterpret_cast<int16_t*>(data+smp);
|
||||||
*l = static_cast<int16_t>(std::clamp(buffer[0][bufPos], -1.0f, 1.0f) * 32767);
|
*l = static_cast<int16_t>(std::clamp(buffer[0][bufPos] * 32768.0f, -32767.0f, 32767.0f));
|
||||||
*r = static_cast<int16_t>(std::clamp(buffer[1][bufPos], -1.0f, 1.0f) * 32767);
|
*r = static_cast<int16_t>(std::clamp(buffer[1][bufPos] * 32768.0f, -32767.0f, 32767.0f));
|
||||||
|
|
||||||
bufPos++;
|
bufPos++;
|
||||||
data += stride;
|
data += stride;
|
||||||
|
|
|
@ -48,17 +48,35 @@ std::array<float, 2> Sample::plotBetween(size_t ch, size_t start, size_t end) co
|
||||||
return {mn, mx};
|
return {mn, mx};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// threshold in MiB-stored-as-float for saving long samples as s16 instead
|
||||||
|
const constexpr double PCM_MiB_THRESHOLD = 5;
|
||||||
|
const constexpr int PCM_THRESHOLD = static_cast<int>(PCM_MiB_THRESHOLD * (1024*1024) / sizeof(float));
|
||||||
QCborMap Sample::toCbor() const {
|
QCborMap Sample::toCbor() const {
|
||||||
QCborMap m;
|
QCborMap m;
|
||||||
|
|
||||||
m[qs("name")] = name;
|
m[qs("name")] = name;
|
||||||
m[qs("rate")] = sampleRate;
|
m[qs("rate")] = sampleRate;
|
||||||
|
|
||||||
|
QString fmt = qs("f32");
|
||||||
|
if (numChannels() * length() > PCM_THRESHOLD) fmt = qs("s16");
|
||||||
|
m[qs("fmt")] = fmt;
|
||||||
|
|
||||||
{
|
{
|
||||||
QCborArray ch;
|
QCborArray ch;
|
||||||
|
|
||||||
auto n = static_cast<size_t>(numChannels());
|
auto n = static_cast<size_t>(numChannels());
|
||||||
for (size_t i = 0; i < n; i++) {
|
if (fmt == qs("f32")) {
|
||||||
ch[static_cast<qsizetype>(i)] = QByteArray(reinterpret_cast<const char*>(data[i].data()), static_cast<int>(data[i].size() * sizeof(data[i][0])));
|
for (size_t i = 0; i < n; i++) {
|
||||||
|
ch[static_cast<qsizetype>(i)] = QByteArray(reinterpret_cast<const char*>(data[i].data()), static_cast<int>(data[i].size() * sizeof(data[i][0])));
|
||||||
|
}
|
||||||
|
} else if (fmt == qs("s16")) {
|
||||||
|
for (size_t i = 0; i < n; i++) {
|
||||||
|
auto sz = data[i].size();
|
||||||
|
QByteArray dat(static_cast<int>(sz * 2), static_cast<char>(0));
|
||||||
|
|
||||||
|
for (size_t j = 0; j < sz; j++) *reinterpret_cast<int16_t*>(dat.data() + j*2) = static_cast<int16_t>(std::clamp(static_cast<double>(data[i][j]) * 32768.0, -32767.0, 32767.0));
|
||||||
|
ch[static_cast<qsizetype>(i)] = dat;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m[qs("channels")] = ch;
|
m[qs("channels")] = ch;
|
||||||
|
@ -82,14 +100,29 @@ std::shared_ptr<Sample> Sample::fromCbor(const QCborMap& m, QUuid uuid) {
|
||||||
|
|
||||||
smp->sampleRate = static_cast<int>(m.value("rate").toInteger(48000));
|
smp->sampleRate = static_cast<int>(m.value("rate").toInteger(48000));
|
||||||
|
|
||||||
|
auto fmt = m.value("fmt").toString(qs("f32"));
|
||||||
|
|
||||||
auto ch = m.value("channels").toArray();
|
auto ch = m.value("channels").toArray();
|
||||||
auto s = static_cast<size_t>(ch.size());
|
auto s = static_cast<size_t>(ch.size());
|
||||||
|
|
||||||
for (size_t i = 0; i < s; i++) {
|
if (fmt == qs("f32")) {
|
||||||
auto c = ch[static_cast<qint64>(i)].toByteArray();
|
for (size_t i = 0; i < s; i++) {
|
||||||
auto bs = static_cast<size_t>(c.size());
|
auto c = ch[static_cast<qint64>(i)].toByteArray();
|
||||||
smp->data[i].resize(bs / sizeof(*smp->data[i].begin()));
|
auto bs = static_cast<size_t>(c.size());
|
||||||
memcpy(smp->data[i].data(), c.constData(), bs);
|
smp->data[i].resize(bs / sizeof(*smp->data[i].begin()));
|
||||||
|
memcpy(smp->data[i].data(), c.constData(), bs);
|
||||||
|
}
|
||||||
|
} else if (fmt == qs("s16")) {
|
||||||
|
for (size_t i = 0; i < s; i++) {
|
||||||
|
auto c = ch[static_cast<qint64>(i)].toByteArray();
|
||||||
|
auto bs = static_cast<size_t>(c.size());
|
||||||
|
auto sz = bs / 2;
|
||||||
|
smp->data[i].resize(sz);
|
||||||
|
for (size_t j = 0; j < sz; j++) {
|
||||||
|
smp->data[i][j] = static_cast<float>(static_cast<double>(*reinterpret_cast<int16_t*>(c.data()+j*2))/32768.0);
|
||||||
|
}
|
||||||
|
//memcpy(smp->data[i].data(), c.constData(), bs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
smp->loopStart = static_cast<int>(m.value("loopStart").toInteger(-1));
|
smp->loopStart = static_cast<int>(m.value("loopStart").toInteger(-1));
|
||||||
|
|
|
@ -35,7 +35,7 @@ namespace {
|
||||||
+ (static_cast<uint32_t>(minor)<<16)
|
+ (static_cast<uint32_t>(minor)<<16)
|
||||||
+ (static_cast<uint32_t>(major)<<24);
|
+ (static_cast<uint32_t>(major)<<24);
|
||||||
}
|
}
|
||||||
constexpr const uint32_t XYBRID_VERSION = packedVersion(0,0,0,1);
|
constexpr const uint32_t XYBRID_VERSION = packedVersion(0,0,0,2);
|
||||||
|
|
||||||
constexpr const QSize dlgSize(700, 500);
|
constexpr const QSize dlgSize(700, 500);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue