Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion architecture/faust/gui/JuceReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,12 @@ struct JuceReader : public SoundfileReader {
if (!formatReader->usesFloatingPointData) {
for (int chan = 0; chan < int(formatReader->numChannels); ++chan) {
if (soundfile->fIsDouble) {
// TODO
double* buffer = &(static_cast<double**>(soundfile->fBuffers))[chan][soundfile->fOffset[part]];
const int* intBuffer = reinterpret_cast<const int*>(buffer);
// Iterate backwards: double (8 bytes) > int (4 bytes), same underlying buffer
for (int i = int(formatReader->lengthInSamples) - 1; i >= 0; --i) {
buffer[i] = double(intBuffer[i]) / double(0x7fffffff);
}
Comment on lines +83 to +88
Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The conversion relies on type-punning the same memory as both double* and int* (reinterpret_cast<const int*>(buffer)) after AudioFormatReader::read() has written 32-bit ints into a double[] buffer. This is undefined behavior in C++ (writing/reading through an incompatible pointer type and partially overwriting double objects) and can break under strict-aliasing/sanitizers. Safer approach: for the fIsDouble && !usesFloatingPointData path, read into a temporary per-channel int32 buffer (or juce::HeapBlock<int>) and then convert into the destination double* buffer (forward iteration is fine then).

Copilot uses AI. Check for mistakes.
Comment on lines +85 to +88
Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The inner loop recomputes double(0x7fffffff) (and performs a division) for every sample. Consider precomputing a const double scale = 1.0 / 0x7fffffff; outside the loop and using multiplication inside to reduce per-sample overhead, especially for long files.

Copilot uses AI. Check for mistakes.
} else {
float* buffer = &(static_cast<float**>(soundfile->fBuffers))[chan][soundfile->fOffset[part]];
juce::FloatVectorOperations::convertFixedToFloat(buffer, reinterpret_cast<const int*>(buffer),
Expand Down