[haiku-commits] haiku: hrev54764 - in src: add-ons/media/media-add-ons/mixer kits/game

  • From: Jérôme Duval <jerome.duval@xxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 8 Dec 2020 07:33:25 -0500 (EST)

hrev54764 adds 2 changesets to branch 'master'
old head: 6cd9975b85858058fd0a289952754b900072bc03
new head: fb6ee7844d0d31441c04674bf6501776868d8e00
overview: 
https://git.haiku-os.org/haiku/log/?qt=range&q=fb6ee7844d0d+%5E6cd9975b8585

----------------------------------------------------------------------------

cfe72209cf7e: U8 sound format
  
  U8 sound has a nonzero value as its zero amplitude, so it needs to be
  special-cased when mixing, applying gains and other transformations.
  
  Change-Id: I5ad96b5f39d454bffad2449ac9f27b2ae61e2ccd
  Reviewed-on: https://review.haiku-os.org/c/haiku/+/3470
  Reviewed-by: Jérôme Duval <jerome.duval@xxxxxxxxx>

fb6ee7844d0d: GameSoundBuffer: avoid buffer copy
  
  Change-Id: Ibffe80ebe5e8205e853e09b6ebb9ba65b53d83e7
  Reviewed-on: https://review.haiku-os.org/c/haiku/+/3475
  Reviewed-by: Jérôme Duval <jerome.duval@xxxxxxxxx>

                                    [ Máximo Castañeda <antiswen@xxxxxxxx> ]

----------------------------------------------------------------------------

5 files changed, 78 insertions(+), 55 deletions(-)
.../media/media-add-ons/mixer/Interpolate.cpp    | 30 ++++++-----
.../media/media-add-ons/mixer/MixerCore.cpp      |  6 ++-
.../media/media-add-ons/mixer/Resampler.cpp      | 26 +++++-----
src/kits/game/FileGameSound.cpp                  | 19 ++++---
src/kits/game/GameSoundBuffer.cpp                | 52 +++++++++++---------

############################################################################

Commit:      cfe72209cf7efc2b6aad94912d4e39a75247bee2
URL:         https://git.haiku-os.org/haiku/commit/?id=cfe72209cf7e
Author:      Máximo Castañeda <antiswen@xxxxxxxx>
Date:        Fri Nov 27 12:08:59 2020 UTC
Committer:   Jérôme Duval <jerome.duval@xxxxxxxxx>
Commit-Date: Tue Dec  8 12:33:22 2020 UTC

U8 sound format

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

Change-Id: I5ad96b5f39d454bffad2449ac9f27b2ae61e2ccd
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3470
Reviewed-by: Jérôme Duval <jerome.duval@xxxxxxxxx>

----------------------------------------------------------------------------

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 17bbbb21f2..48ffd26b3e 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 inMiddle, int outMiddle, 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 @@ kernel(Resampler* object, const void *_src, int32 
srcSampleOffset,
        if (srcSampleCount == destSampleCount) {
                // optimized case for no resampling
                while (count--) {
-                       float tmp = *(const inType*)src * gain + offset;
+                       float tmp = ((*(const inType*)src) - inMiddle) * gain + 
outMiddle;
                        if (tmp < min) tmp = min;
                        if (tmp > max) tmp = max;
                        *(outType *)dest = (outType)tmp;
@@ -50,7 +50,8 @@ kernel(Resampler* object, const void *_src, int32 
srcSampleOffset,
        #define SRC *(const inType*)(src)
 
        while (count--) {
-               float tmp = (gain * (oldSample + (SRC - oldSample) * current) + 
offset);
+               float tmp = (gain * (oldSample + (SRC - oldSample) * current - 
inMiddle)
+                        + outMiddle);
                if (tmp < min) tmp = min;
                if (tmp > max) tmp = max;
                *(outType *)dest = (outType)tmp;
@@ -74,22 +75,25 @@ Interpolate::Interpolate(uint32 src_format, uint32 
dst_format)
        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 @@ Interpolate::Interpolate(uint32 src_format, uint32 
dst_format)
                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 cb832f693d..d34f3fc8ae 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 @@ MixerCore::_MixThread()
                        BBuffer* buffer = fBufferGroup->RequestBuffer(size,
                                bufferRequestTimeout);
                        if (buffer != NULL) {
-                               memset(buffer->Data(), 0, size);
+                               int middle = 0;
+                               if 
(fOutput->MediaOutput().format.u.raw_audio.format
+                                               == 
media_raw_audio_format::B_AUDIO_UCHAR)
+                                       middle = 128;
+                               memset(buffer->Data(), middle, 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 0f4410dc85..58f43fc161 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 inMiddle, int outMiddle, 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 @@ kernel(Resampler* object, const void *_src, int32 
srcSampleOffset,
        if (srcSampleCount == destSampleCount) {
                // optimized case for no resampling
                while (count--) {
-                       float tmp = *(const inType*)src * gain + offset;
+                       float tmp = ((*(const inType*)src) - inMiddle) * gain + 
outMiddle;
                        if (tmp < min) tmp = min;
                        if (tmp > max) tmp = max;
                        *(outType *)dest = (outType)tmp;
@@ -48,7 +48,7 @@ kernel(Resampler* object, const void *_src, int32 
srcSampleOffset,
 
        // downsample
        while (count--) {
-               float tmp = *(const inType*)src * gain + offset;
+               float tmp = ((*(const inType*)src) - inMiddle) * gain + 
outMiddle;
                if (tmp < min) tmp = min;
                if (tmp > max) tmp = max;
                *(outType *)dest = (outType)tmp;
@@ -69,19 +69,19 @@ Resampler::Resampler(uint32 src_format, uint32 dst_format)
        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 @@ Resampler::Resampler(uint32 src_format, uint32 dst_format)
                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 4fcae04cfa..97d1596455 100644
--- a/src/kits/game/FileGameSound.cpp
+++ b/src/kits/game/FileGameSound.cpp
@@ -32,7 +32,7 @@ struct _gs_media_tracker {
 
 
 // Local utility functions -----------------------------------------------
-template<typename T>
+template<typename T, int middle = 0>
 bool
 FillBuffer(_gs_ramp* ramp, T* dest, const T* src, size_t* bytes)
 {
@@ -40,7 +40,7 @@ FillBuffer(_gs_ramp* ramp, T* dest, const T* src, size_t* 
bytes)
 
        for (size_t sample = 0; sample < samples; sample++) {
                float gain = *ramp->value;
-               dest[sample] = T(float(src[sample]) * gain);
+               dest[sample] = T(float(src[sample] - middle) * gain + middle);
 
                if (ChangeRamp(ramp)) {
                        *bytes = sample * sizeof(T);
@@ -206,7 +206,7 @@ BFileGameSound::FillBuffer(void* inBuffer, size_t 
inByteCount)
 
                        switch(Format().format) {
                                case gs_audio_format::B_GS_U8:
-                                       rampDone = ::FillBuffer<uint8>(fPausing,
+                                       rampDone = ::FillBuffer<uint8, 
128>(fPausing,
                                                (uint8*)&buffer[out_offset],
                                                
(uint8*)&fBuffer[fPlayPosition], &bytes);
                                        break;
@@ -245,8 +245,12 @@ BFileGameSound::FillBuffer(void* inBuffer, size_t 
inByteCount)
        }
 
        // Fill the rest with silence
-       if (inByteCount > 0)
-               memset(&buffer[out_offset], 0, inByteCount);
+       if (inByteCount > 0) {
+               int middle = 0;
+               if (Format().format == gs_audio_format::B_GS_U8)
+                       middle = 128;
+               memset(&buffer[out_offset], middle, inByteCount);
+       }
 }
 
 
@@ -362,8 +366,11 @@ BFileGameSound::Init(BDataIO* data)
                fBufferSize = dformat.buffer_size;
 
        // create the buffer
+       int middle = 0;
+       if (gsformat.format == gs_audio_format::B_GS_U8)
+               middle = 128;
        fBuffer = new char[fBufferSize * 2];
-       memset(fBuffer, 0, fBufferSize * 2);
+       memset(fBuffer, middle, 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 f52cde622d..a3a56ea373 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 middle = 0>
 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] - middle) * pan[0] + 
middle);
+       data[index * 2 + 1] += T(float(buffer[index * 2 + 1] - middle) * pan[1]
+                                                       + middle);
 }
 
 
@@ -264,7 +264,7 @@ GameSoundBuffer::Play(void * data, int64 frames)
                        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 @@ GameSoundBuffer::Play(void * data, int64 frames)
                        case gs_audio_format::B_GS_S16:
                        {
                                for (int64 i = 0; i < frames; i++) {
-                                       ApplyMod((int16*)data, (int16*)buffer, 
i, pan);
+                                       ApplyMod<int16>((int16*)data, 
(int16*)buffer, i, pan);
                                        UpdateMods();
                                }
 
@@ -284,7 +284,7 @@ GameSoundBuffer::Play(void * data, int64 frames)
                        case gs_audio_format::B_GS_S32:
                        {
                                for (int64 i = 0; i < frames; i++) {
-                                       ApplyMod((int32*)data, (int32*)buffer, 
i, pan);
+                                       ApplyMod<int32>((int32*)data, 
(int32*)buffer, i, pan);
                                        UpdateMods();
                                }
 
@@ -294,7 +294,7 @@ GameSoundBuffer::Play(void * data, int64 frames)
                        case gs_audio_format::B_GS_F:
                        {
                                for (int64 i = 0; i < frames; i++) {
-                                       ApplyMod((float*)data, (float*)buffer, 
i, pan);
+                                       ApplyMod<float>((float*)data, 
(float*)buffer, i, pan);
                                        UpdateMods();
                                }
 
@@ -512,15 +512,26 @@ SimpleSoundBuffer::FillBuffer(void * data, int64 frames)
                        size_t remainder = fBufferSize - fPosition;
                        memcpy(buffer, &fBuffer[fPosition], remainder);
 
-                       if (fLooping) {
-                               // restart the sound from the begging
-                               memcpy(&buffer[remainder], fBuffer, bytes - 
remainder);
-                               fPosition = bytes - remainder;
-                       } else
-                               fPosition = fBufferSize;
-               } else
-                       memset(data, 0, bytes);
-                       // there is nothing left to play
+                       bytes -= remainder;
+                       buffer += remainder;
+               }
+
+               if (fLooping) {
+                       // restart the sound from the beginning
+                       memcpy(buffer, fBuffer, bytes);
+                       fPosition = bytes;
+                       bytes = 0;
+               } else {
+                       fPosition = fBufferSize;
+               }
+
+               if (bytes > 0) {
+                       // Fill the rest with silence
+                       int middle = 0;
+                       if (fFormat.format == gs_audio_format::B_GS_U8)
+                               middle = 128;
+                       memset(buffer, middle, bytes);
+               }
        } else {
                memcpy(buffer, &fBuffer[fPosition], bytes);
                fPosition += bytes;

############################################################################

Revision:    hrev54764
Commit:      fb6ee7844d0d31441c04674bf6501776868d8e00
URL:         https://git.haiku-os.org/haiku/commit/?id=fb6ee7844d0d
Author:      Máximo Castañeda <antiswen@xxxxxxxx>
Date:        Mon Dec  7 16:15:08 2020 UTC
Committer:   Jérôme Duval <jerome.duval@xxxxxxxxx>
Commit-Date: Tue Dec  8 12:33:22 2020 UTC

GameSoundBuffer: avoid buffer copy

Change-Id: Ibffe80ebe5e8205e853e09b6ebb9ba65b53d83e7
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3475
Reviewed-by: Jérôme Duval <jerome.duval@xxxxxxxxx>

----------------------------------------------------------------------------

diff --git a/src/kits/game/GameSoundBuffer.cpp 
b/src/kits/game/GameSoundBuffer.cpp
index a3a56ea373..aff439b480 100644
--- a/src/kits/game/GameSoundBuffer.cpp
+++ b/src/kits/game/GameSoundBuffer.cpp
@@ -45,10 +45,10 @@
 // Sound Buffer Utility functions ----------------------------------------
 template<typename T, int middle = 0>
 static inline void
-ApplyMod(T* data, T* buffer, int64 index, float * pan)
+ApplyMod(T* data, int64 index, float* pan)
 {
-       data[index * 2] += T(float(buffer[index * 2] - middle) * pan[0] + 
middle);
-       data[index * 2 + 1] += T(float(buffer[index * 2 + 1] - middle) * pan[1]
+       data[index * 2] = T(float(data[index * 2] - middle) * pan[0] + middle);
+       data[index * 2 + 1] = T(float(data[index * 2 + 1] - middle) * pan[1]
                                                        + middle);
 }
 
@@ -256,15 +256,13 @@ GameSoundBuffer::Play(void * data, int64 frames)
                pan[0] = fPanRight * fGain;
                pan[1] = fPanLeft * fGain;
 
-               char * buffer = new char[fFrameSize * frames];
-
-               FillBuffer(buffer, frames);
+               FillBuffer(data, frames);
 
                switch (fFormat.format) {
                        case gs_audio_format::B_GS_U8:
                        {
                                for (int64 i = 0; i < frames; i++) {
-                                       ApplyMod<uint8, 128>((uint8*)data, 
(uint8*)buffer, i, pan);
+                                       ApplyMod<uint8, 128>((uint8*)data, i, 
pan);
                                        UpdateMods();
                                }
 
@@ -274,7 +272,7 @@ GameSoundBuffer::Play(void * data, int64 frames)
                        case gs_audio_format::B_GS_S16:
                        {
                                for (int64 i = 0; i < frames; i++) {
-                                       ApplyMod<int16>((int16*)data, 
(int16*)buffer, i, pan);
+                                       ApplyMod<int16>((int16*)data, i, pan);
                                        UpdateMods();
                                }
 
@@ -284,7 +282,7 @@ GameSoundBuffer::Play(void * data, int64 frames)
                        case gs_audio_format::B_GS_S32:
                        {
                                for (int64 i = 0; i < frames; i++) {
-                                       ApplyMod<int32>((int32*)data, 
(int32*)buffer, i, pan);
+                                       ApplyMod<int32>((int32*)data, i, pan);
                                        UpdateMods();
                                }
 
@@ -294,14 +292,13 @@ GameSoundBuffer::Play(void * data, int64 frames)
                        case gs_audio_format::B_GS_F:
                        {
                                for (int64 i = 0; i < frames; i++) {
-                                       ApplyMod<float>((float*)data, 
(float*)buffer, i, pan);
+                                       ApplyMod<float>((float*)data, i, pan);
                                        UpdateMods();
                                }
 
                                break;
                        }
                }
-               delete[] buffer;
        } else if (fFormat.channel_count == 1) {
                // FIXME the output should be stereo, and we could pan mono 
sounds
                // here. But currently the output has the same number of 
channels as


Other related posts:

  • » [haiku-commits] haiku: hrev54764 - in src: add-ons/media/media-add-ons/mixer kits/game - Jérôme Duval