mirror of https://github.com/encounter/SDL.git
Fix audio conversion when channel count changes
- Use the SDL_AUDIO_MASK_DATATYPE bit when selecting an implementation where it matters. Previously two existing AUDIO_F32 cases had been written, but were unreachable. - Add AUDIO_F32 case for SDL_ConvertSurround_4. - Fix incorrect pointer arithmetic causing the 2 to 6 channel conversion for 4 byte audio formats to read and write beyond the end of the buffer.
This commit is contained in:
parent
5512eac69f
commit
d3cf7360db
|
@ -39,7 +39,9 @@ SDL_ConvertMono(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
||||||
#ifdef DEBUG_CONVERT
|
#ifdef DEBUG_CONVERT
|
||||||
fprintf(stderr, "Converting to mono\n");
|
fprintf(stderr, "Converting to mono\n");
|
||||||
#endif
|
#endif
|
||||||
switch (format & (SDL_AUDIO_MASK_SIGNED | SDL_AUDIO_MASK_BITSIZE)) {
|
switch (format & (SDL_AUDIO_MASK_SIGNED |
|
||||||
|
SDL_AUDIO_MASK_BITSIZE |
|
||||||
|
SDL_AUDIO_MASK_DATATYPE)) {
|
||||||
case AUDIO_U8:
|
case AUDIO_U8:
|
||||||
{
|
{
|
||||||
Uint8 *src, *dst;
|
Uint8 *src, *dst;
|
||||||
|
@ -331,7 +333,9 @@ SDL_ConvertSurround(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
||||||
fprintf(stderr, "Converting stereo to surround\n");
|
fprintf(stderr, "Converting stereo to surround\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
switch (format & (SDL_AUDIO_MASK_SIGNED | SDL_AUDIO_MASK_BITSIZE)) {
|
switch (format & (SDL_AUDIO_MASK_SIGNED |
|
||||||
|
SDL_AUDIO_MASK_BITSIZE |
|
||||||
|
SDL_AUDIO_MASK_DATATYPE)) {
|
||||||
case AUDIO_U8:
|
case AUDIO_U8:
|
||||||
{
|
{
|
||||||
Uint8 *src, *dst, lf, rf, ce;
|
Uint8 *src, *dst, lf, rf, ce;
|
||||||
|
@ -499,8 +503,8 @@ SDL_ConvertSurround(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
||||||
case AUDIO_S32:
|
case AUDIO_S32:
|
||||||
{
|
{
|
||||||
Sint32 lf, rf, ce;
|
Sint32 lf, rf, ce;
|
||||||
const Uint32 *src = (const Uint32 *) cvt->buf + cvt->len_cvt;
|
const Uint32 *src = (const Uint32 *) (cvt->buf + cvt->len_cvt);
|
||||||
Uint32 *dst = (Uint32 *) cvt->buf + cvt->len_cvt * 3;
|
Uint32 *dst = (Uint32 *) (cvt->buf + cvt->len_cvt * 3);
|
||||||
|
|
||||||
if (SDL_AUDIO_ISBIGENDIAN(format)) {
|
if (SDL_AUDIO_ISBIGENDIAN(format)) {
|
||||||
for (i = cvt->len_cvt / 8; i; --i) {
|
for (i = cvt->len_cvt / 8; i; --i) {
|
||||||
|
@ -537,8 +541,8 @@ SDL_ConvertSurround(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
||||||
case AUDIO_F32:
|
case AUDIO_F32:
|
||||||
{
|
{
|
||||||
float lf, rf, ce;
|
float lf, rf, ce;
|
||||||
const float *src = (const float *) cvt->buf + cvt->len_cvt;
|
const float *src = (const float *) (cvt->buf + cvt->len_cvt);
|
||||||
float *dst = (float *) cvt->buf + cvt->len_cvt * 3;
|
float *dst = (float *) (cvt->buf + cvt->len_cvt * 3);
|
||||||
|
|
||||||
if (SDL_AUDIO_ISBIGENDIAN(format)) {
|
if (SDL_AUDIO_ISBIGENDIAN(format)) {
|
||||||
for (i = cvt->len_cvt / 8; i; --i) {
|
for (i = cvt->len_cvt / 8; i; --i) {
|
||||||
|
@ -588,7 +592,9 @@ SDL_ConvertSurround_4(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
||||||
fprintf(stderr, "Converting stereo to quad\n");
|
fprintf(stderr, "Converting stereo to quad\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
switch (format & (SDL_AUDIO_MASK_SIGNED | SDL_AUDIO_MASK_BITSIZE)) {
|
switch (format & (SDL_AUDIO_MASK_SIGNED |
|
||||||
|
SDL_AUDIO_MASK_BITSIZE |
|
||||||
|
SDL_AUDIO_MASK_DATATYPE)) {
|
||||||
case AUDIO_U8:
|
case AUDIO_U8:
|
||||||
{
|
{
|
||||||
Uint8 *src, *dst, lf, rf, ce;
|
Uint8 *src, *dst, lf, rf, ce;
|
||||||
|
@ -762,6 +768,40 @@ SDL_ConvertSurround_4(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case AUDIO_F32:
|
||||||
|
{
|
||||||
|
const float *src = (const float *) (cvt->buf + cvt->len_cvt);
|
||||||
|
float *dst = (float *) (cvt->buf + cvt->len_cvt * 2);
|
||||||
|
float lf, rf, ce;
|
||||||
|
|
||||||
|
if (SDL_AUDIO_ISBIGENDIAN(format)) {
|
||||||
|
for (i = cvt->len_cvt / 8; i; --i) {
|
||||||
|
dst -= 4;
|
||||||
|
src -= 2;
|
||||||
|
lf = SDL_SwapFloatBE(src[0]);
|
||||||
|
rf = SDL_SwapFloatBE(src[1]);
|
||||||
|
ce = (lf / 2) + (rf / 2);
|
||||||
|
dst[0] = src[0];
|
||||||
|
dst[1] = src[1];
|
||||||
|
dst[2] = SDL_SwapFloatBE(lf - ce);
|
||||||
|
dst[3] = SDL_SwapFloatBE(rf - ce);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (i = cvt->len_cvt / 8; i; --i) {
|
||||||
|
dst -= 4;
|
||||||
|
src -= 2;
|
||||||
|
lf = SDL_SwapFloatLE(src[0]);
|
||||||
|
rf = SDL_SwapFloatLE(src[1]);
|
||||||
|
ce = (lf / 2) + (rf / 2);
|
||||||
|
dst[0] = src[0];
|
||||||
|
dst[1] = src[1];
|
||||||
|
dst[2] = SDL_SwapFloatLE(lf - ce);
|
||||||
|
dst[3] = SDL_SwapFloatLE(rf - ce);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
cvt->len_cvt *= 2;
|
cvt->len_cvt *= 2;
|
||||||
if (cvt->filters[++cvt->filter_index]) {
|
if (cvt->filters[++cvt->filter_index]) {
|
||||||
|
|
Loading…
Reference in New Issue