src/audio/SDL_audiotypecvt.c
author Ryan C. Gordon <icculus@icculus.org>
Sun, 15 Jan 2017 05:01:59 -0500
changeset 10814 938218064f67
parent 10799 234f71894a52
child 10815 71bbe3233508
permissions -rw-r--r--
audio: Some fixes to the audio data type converter code.

Removed some needless things ("len / sizeof (Uint8)"), and made sure the
int32 -> float code uses doubles to avoid working with large integer values
in a 32-bit float.
icculus@1982
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@10737
     3
  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
slouken@5535
     4
slouken@5535
     5
  This software is provided 'as-is', without any express or implied
slouken@5535
     6
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     7
  arising from the use of this software.
slouken@5535
     8
slouken@5535
     9
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
    10
  including commercial applications, and to alter it and redistribute it
slouken@5535
    11
  freely, subject to the following restrictions:
slouken@5535
    12
slouken@5535
    13
  1. The origin of this software must not be misrepresented; you must not
slouken@5535
    14
     claim that you wrote the original software. If you use this software
slouken@5535
    15
     in a product, an acknowledgment in the product documentation would be
slouken@5535
    16
     appreciated but is not required.
slouken@5535
    17
  2. Altered source versions must be plainly marked as such, and must not be
slouken@5535
    18
     misrepresented as being the original software.
slouken@5535
    19
  3. This notice may not be removed or altered from any source distribution.
icculus@1982
    20
*/
icculus@1982
    21
icculus@8093
    22
#include "../SDL_internal.h"
icculus@1982
    23
#include "SDL_audio.h"
icculus@1982
    24
#include "SDL_audio_c.h"
icculus@10575
    25
#include "SDL_assert.h"
icculus@1982
    26
icculus@1982
    27
#define DIVBY127 0.0078740157480315f
icculus@1982
    28
#define DIVBY32767 3.05185094759972e-05f
icculus@1982
    29
#define DIVBY2147483647 4.6566128752458e-10f
icculus@1982
    30
icculus@10575
    31
void SDLCALL
icculus@10575
    32
SDL_Convert_S8_to_F32(SDL_AudioCVT *cvt, SDL_AudioFormat format)
icculus@10575
    33
{
icculus@10814
    34
    const Sint8 *src = ((const Sint8 *) (cvt->buf + cvt->len_cvt)) - 1;
icculus@10575
    35
    float *dst = ((float *) (cvt->buf + cvt->len_cvt * 4)) - 1;
icculus@10575
    36
    int i;
icculus@3021
    37
icculus@10575
    38
    LOG_DEBUG_CONVERT("AUDIO_S8", "AUDIO_F32");
icculus@1982
    39
icculus@10814
    40
    for (i = cvt->len_cvt; i; --i, --src, --dst) {
icculus@10814
    41
        *dst = (((float) *src) * DIVBY127);
icculus@1982
    42
    }
icculus@1982
    43
icculus@10575
    44
    cvt->len_cvt *= 4;
icculus@1982
    45
    if (cvt->filters[++cvt->filter_index]) {
icculus@10575
    46
        cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS);
icculus@1982
    47
    }
icculus@1982
    48
}
icculus@1982
    49
icculus@10575
    50
void SDLCALL
icculus@10575
    51
SDL_Convert_U8_to_F32(SDL_AudioCVT *cvt, SDL_AudioFormat format)
icculus@1982
    52
{
icculus@10575
    53
    const Uint8 *src = ((const Uint8 *) (cvt->buf + cvt->len_cvt)) - 1;
icculus@10575
    54
    float *dst = ((float *) (cvt->buf + cvt->len_cvt * 4)) - 1;
icculus@1982
    55
    int i;
icculus@1982
    56
icculus@10575
    57
    LOG_DEBUG_CONVERT("AUDIO_U8", "AUDIO_F32");
icculus@1982
    58
icculus@10814
    59
    for (i = cvt->len_cvt; i; --i, --src, --dst) {
icculus@10575
    60
        *dst = ((((float) *src) * DIVBY127) - 1.0f);
icculus@10575
    61
    }
icculus@10575
    62
icculus@10575
    63
    cvt->len_cvt *= 4;
icculus@10575
    64
    if (cvt->filters[++cvt->filter_index]) {
icculus@10575
    65
        cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS);
icculus@10575
    66
    }
icculus@10575
    67
}
icculus@10575
    68
icculus@10575
    69
void SDLCALL
icculus@10575
    70
SDL_Convert_S16_to_F32(SDL_AudioCVT *cvt, SDL_AudioFormat format)
icculus@10575
    71
{
icculus@10575
    72
    const Sint16 *src = ((const Sint16 *) (cvt->buf + cvt->len_cvt)) - 1;
icculus@10575
    73
    float *dst = ((float *) (cvt->buf + cvt->len_cvt * 2)) - 1;
icculus@10575
    74
    int i;
icculus@10575
    75
icculus@10575
    76
    LOG_DEBUG_CONVERT("AUDIO_S16", "AUDIO_F32");
icculus@10575
    77
icculus@10575
    78
    for (i = cvt->len_cvt / sizeof (Sint16); i; --i, --src, --dst) {
icculus@10575
    79
        *dst = (((float) *src) * DIVBY32767);
icculus@1982
    80
    }
icculus@1982
    81
icculus@1982
    82
    cvt->len_cvt *= 2;
icculus@1982
    83
    if (cvt->filters[++cvt->filter_index]) {
icculus@10575
    84
        cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS);
icculus@1982
    85
    }
icculus@1982
    86
}
icculus@1982
    87
icculus@10575
    88
void SDLCALL
icculus@10575
    89
SDL_Convert_U16_to_F32(SDL_AudioCVT *cvt, SDL_AudioFormat format)
icculus@1982
    90
{
icculus@10575
    91
    const Uint16 *src = ((const Uint16 *) (cvt->buf + cvt->len_cvt)) - 1;
icculus@10575
    92
    float *dst = ((float *) (cvt->buf + cvt->len_cvt * 2)) - 1;
icculus@1982
    93
    int i;
icculus@1982
    94
icculus@10575
    95
    LOG_DEBUG_CONVERT("AUDIO_U16", "AUDIO_F32");
icculus@1982
    96
icculus@10575
    97
    for (i = cvt->len_cvt / sizeof (Uint16); i; --i, --src, --dst) {
icculus@10575
    98
        *dst = ((((float) *src) * DIVBY32767) - 1.0f);
icculus@1982
    99
    }
icculus@1982
   100
icculus@1982
   101
    cvt->len_cvt *= 2;
icculus@1982
   102
    if (cvt->filters[++cvt->filter_index]) {
icculus@10575
   103
        cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS);
icculus@1982
   104
    }
icculus@1982
   105
}
icculus@1982
   106
icculus@10575
   107
void SDLCALL
icculus@10575
   108
SDL_Convert_S32_to_F32(SDL_AudioCVT *cvt, SDL_AudioFormat format)
icculus@1982
   109
{
icculus@10814
   110
    const Sint32 *src = (const Sint32 *) cvt->buf;
icculus@10575
   111
    float *dst = (float *) cvt->buf;
icculus@1982
   112
    int i;
icculus@1982
   113
icculus@10575
   114
    LOG_DEBUG_CONVERT("AUDIO_S32", "AUDIO_F32");
icculus@1982
   115
icculus@10575
   116
    for (i = cvt->len_cvt / sizeof (Sint32); i; --i, ++src, ++dst) {
icculus@10814
   117
        *dst = (float) (((double) *src) * DIVBY2147483647);
icculus@1982
   118
    }
icculus@1982
   119
icculus@1982
   120
    if (cvt->filters[++cvt->filter_index]) {
icculus@10575
   121
        cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS);
icculus@1982
   122
    }
icculus@1982
   123
}
icculus@1982
   124
icculus@10575
   125
void SDLCALL
icculus@10575
   126
SDL_Convert_F32_to_S8(SDL_AudioCVT *cvt, SDL_AudioFormat format)
icculus@1982
   127
{
icculus@10575
   128
    const float *src = (const float *) cvt->buf;
icculus@10575
   129
    Sint8 *dst = (Sint8 *) cvt->buf;
icculus@1982
   130
    int i;
icculus@1982
   131
icculus@10575
   132
    LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_S8");
icculus@1982
   133
icculus@10575
   134
    for (i = cvt->len_cvt / sizeof (float); i; --i, ++src, ++dst) {
icculus@10575
   135
        *dst = (Sint8) (*src * 127.0f);
icculus@1982
   136
    }
icculus@1982
   137
icculus@10575
   138
    cvt->len_cvt /= 4;
icculus@1982
   139
    if (cvt->filters[++cvt->filter_index]) {
icculus@10575
   140
        cvt->filters[cvt->filter_index](cvt, AUDIO_S8);
icculus@1982
   141
    }
icculus@1982
   142
}
icculus@1982
   143
icculus@10575
   144
void SDLCALL
icculus@10575
   145
SDL_Convert_F32_to_U8(SDL_AudioCVT *cvt, SDL_AudioFormat format)
icculus@1982
   146
{
icculus@10575
   147
    const float *src = (const float *) cvt->buf;
icculus@10575
   148
    Uint8 *dst = (Uint8 *) cvt->buf;
icculus@1982
   149
    int i;
icculus@1982
   150
icculus@10575
   151
    LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_U8");
icculus@1982
   152
icculus@10575
   153
    for (i = cvt->len_cvt / sizeof (float); i; --i, ++src, ++dst) {
icculus@10575
   154
        *dst = (Uint8) ((*src + 1.0f) * 127.0f);
icculus@1982
   155
    }
icculus@1982
   156
icculus@10575
   157
    cvt->len_cvt /= 4;
icculus@1982
   158
    if (cvt->filters[++cvt->filter_index]) {
icculus@10575
   159
        cvt->filters[cvt->filter_index](cvt, AUDIO_U8);
icculus@1982
   160
    }
icculus@1982
   161
}
icculus@1982
   162
icculus@10575
   163
void SDLCALL
icculus@10575
   164
SDL_Convert_F32_to_S16(SDL_AudioCVT *cvt, SDL_AudioFormat format)
icculus@1982
   165
{
icculus@10575
   166
    const float *src = (const float *) cvt->buf;
icculus@10575
   167
    Sint16 *dst = (Sint16 *) cvt->buf;
icculus@1982
   168
    int i;
icculus@1982
   169
icculus@10575
   170
    LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_S16");
icculus@1982
   171
icculus@10575
   172
    for (i = cvt->len_cvt / sizeof (float); i; --i, ++src, ++dst) {
icculus@10575
   173
        *dst = (Sint16) (*src * 32767.0f);
icculus@1982
   174
    }
icculus@1982
   175
icculus@1982
   176
    cvt->len_cvt /= 2;
icculus@1982
   177
    if (cvt->filters[++cvt->filter_index]) {
icculus@10575
   178
        cvt->filters[cvt->filter_index](cvt, AUDIO_S16SYS);
icculus@1982
   179
    }
icculus@1982
   180
}
icculus@1982
   181
icculus@10575
   182
void SDLCALL
icculus@10575
   183
SDL_Convert_F32_to_U16(SDL_AudioCVT *cvt, SDL_AudioFormat format)
icculus@1982
   184
{
icculus@10575
   185
    const float *src = (const float *) cvt->buf;
icculus@10575
   186
    Uint16 *dst = (Uint16 *) cvt->buf;
icculus@1982
   187
    int i;
icculus@1982
   188
icculus@10575
   189
    LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_U16");
icculus@1982
   190
icculus@10575
   191
    for (i = cvt->len_cvt / sizeof (float); i; --i, ++src, ++dst) {
icculus@10575
   192
        *dst = (Uint16) ((*src + 1.0f) * 32767.0f);
icculus@1982
   193
    }
icculus@1982
   194
icculus@1982
   195
    cvt->len_cvt /= 2;
icculus@1982
   196
    if (cvt->filters[++cvt->filter_index]) {
icculus@10575
   197
        cvt->filters[cvt->filter_index](cvt, AUDIO_U16SYS);
icculus@1982
   198
    }
icculus@1982
   199
}
icculus@1982
   200
icculus@10575
   201
void SDLCALL
icculus@10575
   202
SDL_Convert_F32_to_S32(SDL_AudioCVT *cvt, SDL_AudioFormat format)
icculus@1982
   203
{
icculus@10575
   204
    const float *src = (const float *) cvt->buf;
icculus@10575
   205
    Sint32 *dst = (Sint32 *) cvt->buf;
icculus@1982
   206
    int i;
icculus@1982
   207
icculus@10575
   208
    LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_S32");
icculus@1982
   209
icculus@10575
   210
    for (i = cvt->len_cvt / sizeof (float); i; --i, ++src, ++dst) {
icculus@10814
   211
        *dst = (Sint32) (((double) *src) * 2147483647.0);
icculus@1982
   212
    }
icculus@1982
   213
icculus@1982
   214
    if (cvt->filters[++cvt->filter_index]) {
icculus@10575
   215
        cvt->filters[cvt->filter_index](cvt, AUDIO_S32SYS);
icculus@1982
   216
    }
icculus@1982
   217
}
icculus@1982
   218
slouken@1985
   219
/* vi: set ts=4 sw=4 expandtab: */