File: alutCodec.c

package info (click to toggle)
freealut 1.1.0-6
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, sid
  • size: 2,144 kB
  • sloc: sh: 8,617; ansic: 2,738; makefile: 89
file content (129 lines) | stat: -rw-r--r-- 3,370 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include "alutInternal.h"

ALvoid *
_alutCodecLinear (ALvoid *data, size_t length, ALint numChannels,
                  ALint bitsPerSample, ALfloat sampleFrequency)
{
  return _alutBufferDataConstruct (data, length, numChannels, bitsPerSample,
                                   sampleFrequency);
}

ALvoid *
_alutCodecPCM8s (ALvoid *data, size_t length, ALint numChannels,
                 ALint bitsPerSample, ALfloat sampleFrequency)
{
  int8_t *d = (int8_t *) data;
  size_t i;
  for (i = 0; i < length; i++)
    {
      d[i] += (int8_t) 128;
    }
  return _alutBufferDataConstruct (data, length, numChannels, bitsPerSample,
                                   sampleFrequency);
}

ALvoid *
_alutCodecPCM16 (ALvoid *data, size_t length, ALint numChannels,
                 ALint bitsPerSample, ALfloat sampleFrequency)
{
  int16_t *d = (int16_t *) data;
  size_t i, l = length / 2;
  for (i = 0; i < l; i++)
    {
      int16_t x = d[i];
      d[i] = ((x << 8) & 0xFF00) | ((x >> 8) & 0x00FF);
    }
  return _alutBufferDataConstruct (data, length, numChannels, bitsPerSample,
                                   sampleFrequency);
}

/*
 * From: http://www.multimedia.cx/simpleaudio.html#tth_sEc6.1
 */
static int16_t
mulaw2linear (uint8_t mulawbyte)
{
  static const int16_t exp_lut[8] = {
    0, 132, 396, 924, 1980, 4092, 8316, 16764
  };
  int16_t sign, exponent, mantissa, sample;
  mulawbyte = ~mulawbyte;
  sign = (mulawbyte & 0x80);
  exponent = (mulawbyte >> 4) & 0x07;
  mantissa = mulawbyte & 0x0F;
  sample = exp_lut[exponent] + (mantissa << (exponent + 3));
  if (sign != 0)
    {
      sample = -sample;
    }
  return sample;
}

ALvoid *
_alutCodecULaw (ALvoid *data, size_t length, ALint numChannels,
                ALint bitsPerSample, ALfloat sampleFrequency)
{
  uint8_t *d = (uint8_t *) data;
  int16_t *buf = (int16_t *) _alutMalloc (length * 2);
  size_t i;
  if (buf == NULL)
    {
      return NULL;
    }
  for (i = 0; i < length; i++)
    {
      buf[i] = mulaw2linear (d[i]);
    }
  free (data);
  return _alutBufferDataConstruct (buf, length * 2, numChannels,
                                   bitsPerSample, sampleFrequency);
}

/*
 * From: http://www.multimedia.cx/simpleaudio.html#tth_sEc6.1
 */
#define SIGN_BIT (0x80)         /* Sign bit for a A-law byte. */
#define QUANT_MASK (0xf)        /* Quantization field mask. */
#define SEG_SHIFT (4)           /* Left shift for segment number. */
#define SEG_MASK (0x70)         /* Segment field mask. */
static int16_t
alaw2linear (uint8_t a_val)
{
  int16_t t, seg;
  a_val ^= 0x55;
  t = (a_val & QUANT_MASK) << 4;
  seg = ((int16_t) a_val & SEG_MASK) >> SEG_SHIFT;
  switch (seg)
    {
    case 0:
      t += 8;
      break;
    case 1:
      t += 0x108;
      break;
    default:
      t += 0x108;
      t <<= seg - 1;
    }
  return (a_val & SIGN_BIT) ? t : -t;
}

ALvoid *
_alutCodecALaw (ALvoid *data, size_t length, ALint numChannels,
                ALint bitsPerSample, ALfloat sampleFrequency)
{
  uint8_t *d = (uint8_t *) data;
  int16_t *buf = (int16_t *) _alutMalloc (length * 2);
  size_t i;
  if (buf == NULL)
    {
      return NULL;
    }
  for (i = 0; i < length; i++)
    {
      buf[i] = alaw2linear (d[i]);
    }
  free (data);
  return _alutBufferDataConstruct (buf, length * 2, numChannels,
                                   bitsPerSample, sampleFrequency);
}