[haiku-commits] Change in haiku[master]: U8 sound format

  • From: Gerrit <review@xxxxxxxxxxxxxxxxxxx>
  • To: waddlesplash <waddlesplash@xxxxxxxxx>, haiku-commits@xxxxxxxxxxxxx
  • Date: Sun, 6 Dec 2020 16:54:50 +0000

From Máximo Castañeda <antiswen@xxxxxxxx>:

Máximo Castañeda has uploaded this change for review. ( 
https://review.haiku-os.org/c/haiku/+/3470 ;)


Change subject: U8 sound format
......................................................................

U8 sound format

U8 sound has a nonzero value as its zero amplitude, so it needs to be
special-cased when mixing, aplying gains and other transformations.

Change-Id: I5ad96b5f39d454bffad2449ac9f27b2ae61e2ccd
---
M src/add-ons/media/media-add-ons/mixer/Interpolate.cpp
M src/add-ons/media/media-add-ons/mixer/MixerCore.cpp
M src/add-ons/media/media-add-ons/mixer/Resampler.cpp
M src/kits/game/FileGameSound.cpp
M src/kits/game/GameSoundBuffer.cpp
5 files changed, 67 insertions(+), 42 deletions(-)



  git pull ssh://git.haiku-os.org:22/haiku refs/changes/70/3470/1

diff --git a/src/add-ons/media/media-add-ons/mixer/Interpolate.cpp 
b/src/add-ons/media/media-add-ons/mixer/Interpolate.cpp
index 17bbbb2..d0ae03f 100644
--- a/src/add-ons/media/media-add-ons/mixer/Interpolate.cpp
+++ b/src/add-ons/media/media-add-ons/mixer/Interpolate.cpp
@@ -19,8 +19,8 @@
 */


-template<typename inType, typename outType, int gnum, int gden, int offset,
-       int32 min, int32 max> static void
+template<typename inType, typename outType, int gnum, int gden,
+       int inZero, int outZero, int32 min, int32 max> static void
 kernel(Resampler* object, const void *_src, int32 srcSampleOffset,
        int32 srcSampleCount, void *_dest, int32 destSampleOffset,
        int32 destSampleCount, float _gain)
@@ -33,7 +33,7 @@
        if (srcSampleCount == destSampleCount) {
                // optimized case for no resampling
                while (count--) {
-                       float tmp = *(const inType*)src * gain + offset;
+                       float tmp = ((*(const inType*)src) - inZero) * gain + 
outZero;
                        if (tmp < min) tmp = min;
                        if (tmp > max) tmp = max;
                        *(outType *)dest = (outType)tmp;
@@ -50,7 +50,8 @@
        #define SRC *(const inType*)(src)

        while (count--) {
-               float tmp = (gain * (oldSample + (SRC - oldSample) * current) + 
offset);
+               float tmp = (gain * (oldSample + (SRC - oldSample) * current - 
inZero)
+                        + outZero);
                if (tmp < min) tmp = min;
                if (tmp > max) tmp = max;
                *(outType *)dest = (outType)tmp;
@@ -74,22 +75,25 @@
        Resampler(),
        fOldSample(0)
 {
+       if (src_format == media_raw_audio_format::B_AUDIO_UCHAR)
+               fOldSample = 128;
+
        if (dst_format == media_raw_audio_format::B_AUDIO_FLOAT) {
                switch (src_format) {
                        case media_raw_audio_format::B_AUDIO_FLOAT:
-                               fFunc = &kernel<float, float, 1, 1, 0, -1, 1>;
+                               fFunc = &kernel<float, float, 1, 1, 0, 0, -1, 
1>;
                                return;
                        case media_raw_audio_format::B_AUDIO_INT:
-                               fFunc = &kernel<int32, float, 1, INT32_MAX, 0, 
-1, 1>;
+                               fFunc = &kernel<int32, float, 1, INT32_MAX, 0, 
0, -1, 1>;
                                return;
                        case media_raw_audio_format::B_AUDIO_SHORT:
-                               fFunc = &kernel<int16, float, 1, INT16_MAX, 0, 
-1, 1>;
+                               fFunc = &kernel<int16, float, 1, INT16_MAX, 0, 
0, -1, 1>;
                                return;
                        case media_raw_audio_format::B_AUDIO_CHAR:
-                               fFunc = &kernel<int8, float, 1, INT8_MAX, 0, 
-1, 1>;
+                               fFunc = &kernel<int8, float, 1, INT8_MAX, 0, 0, 
-1, 1>;
                                return;
                        case media_raw_audio_format::B_AUDIO_UCHAR:
-                               fFunc = &kernel<uint8, float, 2, UINT8_MAX, 
-128, -1, 1>;
+                               fFunc = &kernel<uint8, float, 2, UINT8_MAX, 
128, 0, -1, 1>;
                                return;
                        default:
                                ERROR("Resampler::Resampler: unknown source 
format 0x%x\n",
@@ -102,19 +106,19 @@
                switch (dst_format) {
                        // float=>float already handled above
                        case media_raw_audio_format::B_AUDIO_INT:
-                               fFunc = &kernel<float, int32, INT32_MAX, 1, 0,
+                               fFunc = &kernel<float, int32, INT32_MAX, 1, 0, 
0,
                                        INT32_MIN, INT32_MAX>;
                                return;
                        case media_raw_audio_format::B_AUDIO_SHORT:
-                               fFunc = &kernel<float, int16, INT16_MAX, 1, 0,
+                               fFunc = &kernel<float, int16, INT16_MAX, 1, 0, 
0,
                                        INT16_MIN, INT16_MAX>;
                                return;
                        case media_raw_audio_format::B_AUDIO_CHAR:
-                               fFunc = &kernel<float, int8, INT8_MAX, 1, 0,
+                               fFunc = &kernel<float, int8, INT8_MAX, 1, 0, 0,
                                        INT8_MIN, INT8_MAX>;
                                return;
                        case media_raw_audio_format::B_AUDIO_UCHAR:
-                               fFunc = &kernel<float, uint8, UINT8_MAX, 2, 1,
+                               fFunc = &kernel<float, uint8, UINT8_MAX, 2, 0, 
128,
                                        0, UINT8_MAX>;
                                return;
                        default:
diff --git a/src/add-ons/media/media-add-ons/mixer/MixerCore.cpp 
b/src/add-ons/media/media-add-ons/mixer/MixerCore.cpp
index cb832f6..fd0c1a5 100644
--- a/src/add-ons/media/media-add-ons/mixer/MixerCore.cpp
+++ b/src/add-ons/media/media-add-ons/mixer/MixerCore.cpp
@@ -557,7 +557,11 @@
                        BBuffer* buffer = fBufferGroup->RequestBuffer(size,
                                bufferRequestTimeout);
                        if (buffer != NULL) {
-                               memset(buffer->Data(), 0, size);
+                               if 
(fOutput->MediaOutput().format.u.raw_audio.format
+                                               != 
media_raw_audio_format::B_AUDIO_UCHAR)
+                                       memset(buffer->Data(), 0, size);
+                               else
+                                       memset(buffer->Data(), 128, size);
                                // fill in the buffer header
                                media_header* hdr = buffer->Header();
                                hdr->type = B_MEDIA_RAW_AUDIO;
diff --git a/src/add-ons/media/media-add-ons/mixer/Resampler.cpp 
b/src/add-ons/media/media-add-ons/mixer/Resampler.cpp
index 0f4410d..cd95e5e 100644
--- a/src/add-ons/media/media-add-ons/mixer/Resampler.cpp
+++ b/src/add-ons/media/media-add-ons/mixer/Resampler.cpp
@@ -19,8 +19,8 @@
 */


-template<typename inType, typename outType, int gnum, int gden, int offset,
-       int32 min, int32 max> static void
+template<typename inType, typename outType, int gnum, int gden,
+       int inZero, int outZero, int32 min, int32 max> static void
 kernel(Resampler* object, const void *_src, int32 srcSampleOffset,
        int32 srcSampleCount, void *_dest, int32 destSampleOffset,
        int32 destSampleCount, float _gain)
@@ -33,7 +33,7 @@
        if (srcSampleCount == destSampleCount) {
                // optimized case for no resampling
                while (count--) {
-                       float tmp = *(const inType*)src * gain + offset;
+                       float tmp = ((*(const inType*)src) - inZero) * gain + 
outZero;
                        if (tmp < min) tmp = min;
                        if (tmp > max) tmp = max;
                        *(outType *)dest = (outType)tmp;
@@ -48,7 +48,7 @@

        // downsample
        while (count--) {
-               float tmp = *(const inType*)src * gain + offset;
+               float tmp = ((*(const inType*)src) - inZero) * gain + outZero;
                if (tmp < min) tmp = min;
                if (tmp > max) tmp = max;
                *(outType *)dest = (outType)tmp;
@@ -69,19 +69,19 @@
        if (dst_format == media_raw_audio_format::B_AUDIO_FLOAT) {
                switch (src_format) {
                        case media_raw_audio_format::B_AUDIO_FLOAT:
-                               fFunc = &kernel<float, float, 1, 1, 0, -1, 1>;
+                               fFunc = &kernel<float, float, 1, 1, 0, 0, -1, 
1>;
                                return;
                        case media_raw_audio_format::B_AUDIO_INT:
-                               fFunc = &kernel<int32, float, 1, INT32_MAX, 0, 
-1, 1>;
+                               fFunc = &kernel<int32, float, 1, INT32_MAX, 0, 
0, -1, 1>;
                                return;
                        case media_raw_audio_format::B_AUDIO_SHORT:
-                               fFunc = &kernel<int16, float, 1, INT16_MAX, 0, 
-1, 1>;
+                               fFunc = &kernel<int16, float, 1, INT16_MAX, 0, 
0, -1, 1>;
                                return;
                        case media_raw_audio_format::B_AUDIO_CHAR:
-                               fFunc = &kernel<int8, float, 1, INT8_MAX, 0, 
-1, 1>;
+                               fFunc = &kernel<int8, float, 1, INT8_MAX, 0, 0, 
-1, 1>;
                                return;
                        case media_raw_audio_format::B_AUDIO_UCHAR:
-                               fFunc = &kernel<uint8, float, 2, UINT8_MAX, 
-128, -1, 1>;
+                               fFunc = &kernel<uint8, float, 2, UINT8_MAX, 
128, 0, -1, 1>;
                                return;
                        default:
                                ERROR("Resampler::Resampler: unknown source 
format 0x%x\n",
@@ -94,19 +94,19 @@
                switch (dst_format) {
                        // float=>float already handled above
                        case media_raw_audio_format::B_AUDIO_INT:
-                               fFunc = &kernel<float, int32, INT32_MAX, 1, 0,
+                               fFunc = &kernel<float, int32, INT32_MAX, 1, 0, 
0,
                                        INT32_MIN, INT32_MAX>;
                                return;
                        case media_raw_audio_format::B_AUDIO_SHORT:
-                               fFunc = &kernel<float, int16, INT16_MAX, 1, 0,
+                               fFunc = &kernel<float, int16, INT16_MAX, 1, 0, 
0,
                                        INT16_MIN, INT16_MAX>;
                                return;
                        case media_raw_audio_format::B_AUDIO_CHAR:
-                               fFunc = &kernel<float, int8, INT8_MAX, 1, 0,
+                               fFunc = &kernel<float, int8, INT8_MAX, 1, 0, 0,
                                        INT8_MIN, INT8_MAX>;
                                return;
                        case media_raw_audio_format::B_AUDIO_UCHAR:
-                               fFunc = &kernel<float, uint8, UINT8_MAX, 2, 1,
+                               fFunc = &kernel<float, uint8, UINT8_MAX, 2, 0, 
128,
                                        0, UINT8_MAX>;
                                return;
                        default:
diff --git a/src/kits/game/FileGameSound.cpp b/src/kits/game/FileGameSound.cpp
index 7749467..ecfb005 100644
--- a/src/kits/game/FileGameSound.cpp
+++ b/src/kits/game/FileGameSound.cpp
@@ -39,7 +39,7 @@

        for (int32 byte = 0; byte < samples; byte++) {
                float gain = *ramp->value;
-               data[byte] = uint8(float(buffer[byte]) * gain);
+               data[byte] = uint8(float(buffer[byte] - 128) * gain + 128);

                if (ChangeRamp(ramp)) {
                        *bytes = byte * sizeof(uint8);
@@ -328,8 +328,12 @@
        }

        // Fill the rest with silence
-       if (inByteCount > 0)
-               memset(&buffer[out_offset], 0, inByteCount);
+       if (inByteCount > 0) {
+               if (Format().format != gs_audio_format::B_GS_U8)
+                       memset(&buffer[out_offset], 0, inByteCount);
+               else
+                       memset(&buffer[out_offset], 128, inByteCount);
+       }
 }


@@ -446,7 +450,10 @@

        // create the buffer
        fBuffer = new char[fBufferSize * 2];
-       memset(fBuffer, 0, fBufferSize * 2);
+       if (gsformat.format != gs_audio_format::B_GS_U8)
+               memset(fBuffer, 0, fBufferSize * 2);
+       else
+               memset(fBuffer, 128, fBufferSize * 2);

        fFrameSize = gsformat.channel_count * get_sample_size(gsformat.format);
        fAudioStream->frames = fAudioStream->stream->CountFrames();
diff --git a/src/kits/game/GameSoundBuffer.cpp 
b/src/kits/game/GameSoundBuffer.cpp
index f52cde6..addda9d 100644
--- a/src/kits/game/GameSoundBuffer.cpp
+++ b/src/kits/game/GameSoundBuffer.cpp
@@ -42,14 +42,14 @@
 #include "StreamingGameSound.h"
 #include "GSUtility.h"

-
 // Sound Buffer Utility functions ----------------------------------------
-template<typename T>
+template<typename T, int zero>
 static inline void
 ApplyMod(T* data, T* buffer, int64 index, float * pan)
 {
-       data[index * 2] += T(float(buffer[index * 2]) * pan[0]);
-       data[index * 2 + 1] += T(float(buffer[index * 2 + 1]) * pan[1]);
+       data[index * 2] += T(float(buffer[index * 2] - zero) * pan[0] + zero);
+       data[index * 2 + 1] += T(float(buffer[index * 2 + 1] - zero) * pan[1]
+                                                       + zero);
 }


@@ -264,7 +264,7 @@
                        case gs_audio_format::B_GS_U8:
                        {
                                for (int64 i = 0; i < frames; i++) {
-                                       ApplyMod((uint8*)data, (uint8*)buffer, 
i, pan);
+                                       ApplyMod<uint8, 128>((uint8*)data, 
(uint8*)buffer, i, pan);
                                        UpdateMods();
                                }

@@ -274,7 +274,7 @@
                        case gs_audio_format::B_GS_S16:
                        {
                                for (int64 i = 0; i < frames; i++) {
-                                       ApplyMod((int16*)data, (int16*)buffer, 
i, pan);
+                                       ApplyMod<int16, 0>((int16*)data, 
(int16*)buffer, i, pan);
                                        UpdateMods();
                                }

@@ -284,7 +284,7 @@
                        case gs_audio_format::B_GS_S32:
                        {
                                for (int64 i = 0; i < frames; i++) {
-                                       ApplyMod((int32*)data, (int32*)buffer, 
i, pan);
+                                       ApplyMod<int32, 0>((int32*)data, 
(int32*)buffer, i, pan);
                                        UpdateMods();
                                }

@@ -294,7 +294,7 @@
                        case gs_audio_format::B_GS_F:
                        {
                                for (int64 i = 0; i < frames; i++) {
-                                       ApplyMod((float*)data, (float*)buffer, 
i, pan);
+                                       ApplyMod<float, 0>((float*)data, 
(float*)buffer, i, pan);
                                        UpdateMods();
                                }

@@ -516,11 +516,21 @@
                                // restart the sound from the begging
                                memcpy(&buffer[remainder], fBuffer, bytes - 
remainder);
                                fPosition = bytes - remainder;
-                       } else
+                       } else {
+                               // Fill the rest with silence
+                               if (fFormat.format != gs_audio_format::B_GS_U8)
+                                       memset(&buffer[remainder], 0, bytes - 
remainder);
+                               else
+                                       memset(&buffer[remainder], 128, bytes - 
remainder);
                                fPosition = fBufferSize;
-               } else
-                       memset(data, 0, bytes);
+                       }
+               } else {
                        // there is nothing left to play
+                       if (fFormat.format != gs_audio_format::B_GS_U8)
+                               memset(data, 0, bytes);
+                       else
+                               memset(data, 128, bytes);
+               }
        } else {
                memcpy(buffer, &fBuffer[fPosition], bytes);
                fPosition += bytes;

--
To view, visit https://review.haiku-os.org/c/haiku/+/3470
To unsubscribe, or for help writing mail filters, visit 
https://review.haiku-os.org/settings

Gerrit-Project: haiku
Gerrit-Branch: master
Gerrit-Change-Id: I5ad96b5f39d454bffad2449ac9f27b2ae61e2ccd
Gerrit-Change-Number: 3470
Gerrit-PatchSet: 1
Gerrit-Owner: Máximo Castañeda <antiswen@xxxxxxxx>
Gerrit-MessageType: newchange

Other related posts:

  • » [haiku-commits] Change in haiku[master]: U8 sound format - Gerrit