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