Skip to content

Commit c38c55f

Browse files
authored
Merge pull request #466 from SuslikV/float-to-int16
Fix distortion during mix of audio
2 parents fda1357 + 455b6e9 commit c38c55f

File tree

4 files changed

+38
-14
lines changed

4 files changed

+38
-14
lines changed

src/FFmpegReader.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1627,9 +1627,8 @@ void FFmpegReader::ProcessAudioPacket(int64_t requested_frame, int64_t target_fr
16271627
else
16281628
partial_frame = true;
16291629

1630-
// Add samples for current channel to the frame. Reduce the volume to 98%, to prevent
1631-
// some louder samples from maxing out at 1.0 (not sure why this happens)
1632-
f->AddAudio(true, channel_filter, start, iterate_channel_buffer, samples, 0.98f);
1630+
// Add samples for current channel to the frame.
1631+
f->AddAudio(true, channel_filter, start, iterate_channel_buffer, samples, 1.0f);
16331632

16341633
// Debug output
16351634
ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::ProcessAudioPacket (f->AddAudio)", "frame", starting_frame_number, "start", start, "samples", samples, "channel", channel_filter, "partial_frame", partial_frame, "samples_per_frame", samples_per_frame);

src/FFmpegWriter.cpp

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1525,11 +1525,23 @@ void FFmpegWriter::write_audio_packets(bool is_final) {
15251525
// Calculate total samples
15261526
total_frame_samples = samples_in_frame * channels_in_frame;
15271527

1528-
// Translate audio sample values back to 16 bit integers
1529-
for (int s = 0; s < total_frame_samples; s++, frame_position++)
1530-
// Translate sample value and copy into buffer
1531-
all_queued_samples[frame_position] = int(frame_samples_float[s] * (1 << 15));
1532-
1528+
// Translate audio sample values back to 16 bit integers with saturation
1529+
float valF;
1530+
int16_t conv;
1531+
const int16_t max16 = 32767;
1532+
const int16_t min16 = -32768;
1533+
for (int s = 0; s < total_frame_samples; s++, frame_position++) {
1534+
valF = frame_samples_float[s] * (1 << 15);
1535+
if (valF > max16)
1536+
conv = max16;
1537+
else if (valF < min16)
1538+
conv = min16;
1539+
else
1540+
conv = int(valF + 32768.5) - 32768; // +0.5 is for rounding
1541+
1542+
// Copy into buffer
1543+
all_queued_samples[frame_position] = conv;
1544+
}
15331545

15341546
// Deallocate float array
15351547
delete[] frame_samples_float;

src/FrameMapper.cpp

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -785,10 +785,23 @@ void FrameMapper::ResampleMappedAudio(std::shared_ptr<Frame> frame, int64_t orig
785785
// Create a new array (to hold all S16 audio samples for the current queued frames)
786786
int16_t* frame_samples = (int16_t*) av_malloc(sizeof(int16_t)*total_frame_samples);
787787

788-
// Translate audio sample values back to 16 bit integers
789-
for (int s = 0; s < total_frame_samples; s++)
790-
// Translate sample value and copy into buffer
791-
frame_samples[s] = int(frame_samples_float[s] * (1 << 15));
788+
// Translate audio sample values back to 16 bit integers with saturation
789+
float valF;
790+
int16_t conv;
791+
const int16_t max16 = 32767;
792+
const int16_t min16 = -32768;
793+
for (int s = 0; s < total_frame_samples; s++) {
794+
valF = frame_samples_float[s] * (1 << 15);
795+
if (valF > max16)
796+
conv = max16;
797+
else if (valF < min16)
798+
conv = min16;
799+
else
800+
conv = int(valF + 32768.5) - 32768; // +0.5 is for rounding
801+
802+
// Copy into buffer
803+
frame_samples[s] = conv;
804+
}
792805

793806

794807
// Deallocate float array

tests/FFmpegReader_Tests.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ TEST(FFmpegReader_Check_Audio_File)
7676
CHECK_CLOSE(0.0f, samples[50], 0.00001);
7777
CHECK_CLOSE(0.0f, samples[100], 0.00001);
7878
CHECK_CLOSE(0.0f, samples[200], 0.00001);
79-
CHECK_CLOSE(0.160781f, samples[230], 0.00001);
80-
CHECK_CLOSE(-0.06125f, samples[300], 0.00001);
79+
CHECK_CLOSE(0.16406f, samples[230], 0.00001);
80+
CHECK_CLOSE(-0.06250f, samples[300], 0.00001);
8181

8282
// Close reader
8383
r.Close();

0 commit comments

Comments
 (0)