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