Home My Page Projects Code Snippets Project Openings 3D graphics for Standard ML
Summary Activity SCM

SCM Repository

[sml3d] View of /trunk/sml3d/src/openal/codec.c
ViewVC logotype

View of /trunk/sml3d/src/openal/codec.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 888 - (download) (as text) (annotate)
Tue May 11 17:00:26 2010 UTC (9 years, 6 months ago) by jhr
File size: 8326 byte(s)
  Working on OpenAL glue code
/*! \file codec.c
 *
 * \author John Reppy
 *
 * Codecs for decoding audio files.
 */

/*
 * COPYRIGHT (c) 2010 John Reppy (http://cs.uchicago.edu/~jhr)
 * All rights reserved.
 *
 * This code is based on code in the freealut-1.1.0 sources, which is
 * available from http://openal.org
 */

/* see http://wiki.multimedia.cx/index.php?title=PCM for more info */

#include "openal-glue.h"


/*! \brief linear codec for raw-data formats.
 *  \param data		  pointer to audio data
 *  \param len		  number of bytes of data
 *  \param nChans	  number of channels
 *  \param bitsPerSample  number of bits per channel
 *  \param freq		  sample frequency
 *  \return		  data buffer with decoded audio
 */
BufferData_t *SML3D_RawCodec (void *data, size_t len, int nChans, int bitsPerSample, float freq)
{
    return NewBufferData (data, len, nChans, bitsPerSample, freq);
}

/*! \brief Codec for 8-bit signed PCM data
 *  \param data		  pointer to audio data
 *  \param len		  number of bytes of data
 *  \param nChans	  number of channels
 *  \param bitsPerSample  number of bits per channel
 *  \param freq		  sample frequency
 *  \return		  data buffer with decoded audio
 */
BufferData_t *SML3D_PCM8sCodec (void *data, size_t len, int nChans, int bitsPerSample, float freq)
{
    BufferData_t *buf = NewBufferData (data, len, nChans, bitsPerSample, freq);

    if (buf != 0) {
      // convert signed data to unsigned data
	int8_t *dp = (int8_t *)data;
	for (int i = 0;  i < len;  i++) {
	    dp[i] += (int8_t)128;
	}
    }

    return buf;
}

/*! \brief Codec for 16-bit PCM data
 *  \param data		  pointer to audio data
 *  \param len		  number of bytes of data
 *  \param nChans	  number of channels
 *  \param bitsPerSample  number of bits per channel
 *  \param freq		  sample frequency
 *  \return		  data buffer with decoded audio
 */
BufferData_t *SML3D_PCM16Codec (void *data, size_t len, int nChans, int bitsPerSample, float freq)
{
    BufferData_t *buf = NewBufferData (data, len, nChans, bitsPerSample, freq);

    if (buf != 0) {
#ifndef WORDS_BIGENDIAN
      // convert to little-endian
	int16_t *dp = (int16_t *)data;
	size_t l = len / 2;
	for (size_t i = 0;  i < l;  i++) {
	    int16_t x = dp[i];
	    dp[i] = ((x << 8) & 0xFF00) | ((x >> 8) & 0x00FF);
	}
#endif
    }

    return buf;
}

/* mu-Law decompression table (see http://hazelware.luggle.com/tutorials/mulawcompression.html) */
static int16_t muLaw2Linear[256] = {
	-32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956, 
	-23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764, 
	-15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412, 
	-11900, -11388, -10876, -10364,  -9852,  -9340,  -8828,  -8316, 
	 -7932,  -7676,  -7420,  -7164,  -6908,  -6652,  -6396,  -6140, 
	 -5884,  -5628,  -5372,  -5116,  -4860,  -4604,  -4348,  -4092, 
	 -3900,  -3772,  -3644,  -3516,  -3388,  -3260,  -3132,  -3004, 
	 -2876,  -2748,  -2620,  -2492,  -2364,  -2236,  -2108,  -1980, 
	 -1884,  -1820,  -1756,  -1692,  -1628,  -1564,  -1500,  -1436, 
	 -1372,  -1308,  -1244,  -1180,  -1116,  -1052,   -988,   -924, 
	  -876,   -844,   -812,   -780,   -748,   -716,   -684,   -652, 
	  -620,   -588,   -556,   -524,   -492,   -460,   -428,   -396, 
	  -372,   -356,   -340,   -324,   -308,   -292,   -276,   -260, 
	  -244,   -228,   -212,   -196,   -180,   -164,   -148,   -132, 
	  -120,   -112,   -104,    -96,    -88,    -80,    -72,    -64, 
	   -56,    -48,    -40,    -32,    -24,    -16,     -8,      0, 
	 32124,  31100,  30076,  29052,  28028,  27004,  25980,  24956, 
	 23932,  22908,  21884,  20860,  19836,  18812,  17788,  16764, 
	 15996,  15484,  14972,  14460,  13948,  13436,  12924,  12412, 
	 11900,  11388,  10876,  10364,   9852,   9340,   8828,   8316, 
	  7932,   7676,   7420,   7164,   6908,   6652,   6396,   6140, 
	  5884,   5628,   5372,   5116,   4860,   4604,   4348,   4092, 
	  3900,   3772,   3644,   3516,   3388,   3260,   3132,   3004, 
	  2876,   2748,   2620,   2492,   2364,   2236,   2108,   1980, 
	  1884,   1820,   1756,   1692,   1628,   1564,   1500,   1436, 
	  1372,   1308,   1244,   1180,   1116,   1052,    988,    924, 
	   876,    844,    812,    780,    748,    716,    684,    652, 
	   620,    588,    556,    524,    492,    460,    428,    396, 
	   372,    356,    340,    324,    308,    292,    276,    260, 
	   244,    228,    212,    196,    180,    164,    148,    132, 
	   120,    112,    104,     96,     88,     80,     72,     64, 
	    56,     48,     40,     32,     24,     16,      8,      0, 
    };

/*! \brief Codec for 8-bit mu-Law encoded data
 *  \param data		  pointer to audio data
 *  \param len		  number of bytes of data
 *  \param nChans	  number of channels
 *  \param bitsPerSample  number of bits per channel
 *  \param freq		  sample frequency
 *  \return		  data buffer with decoded audio
 */
BufferData_t *SML3D_muLawCodec (void *data, size_t len, int nChans, int bitsPerSample, float freq)
{
    int16_t *dst = (int16_t *)malloc(2 * len);
    BufferData_t *buf = NewBufferData (dst, 2*len, nChans, bitsPerSample, freq);

    if (buf != 0) {
      // convert to raw encoding
	int8_t *dp = (int8_t *)data;
	for (size_t i = 0;  i < len;  i++) {
	    dst[i] = muLaw2Linear[dp[i]];
	}
    }
    else if (dst != 0)
	free (dst);

    return buf;
}


/* A-Law decompression table (see http://hazelware.luggle.com/tutorials/mulawcompression.html) */
static int16_t ALaw2Linear[256] = {
	 -5504,  -5248,  -6016,  -5760,  -4480,  -4224,  -4992,  -4736, 
	 -7552,  -7296,  -8064,  -7808,  -6528,  -6272,  -7040,  -6784, 
	 -2752,  -2624,  -3008,  -2880,  -2240,  -2112,  -2496,  -2368, 
	 -3776,  -3648,  -4032,  -3904,  -3264,  -3136,  -3520,  -3392, 
	-22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944, 
	-30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136, 
	-11008, -10496, -12032, -11520,  -8960,  -8448,  -9984,  -9472, 
	-15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568, 
	  -344,   -328,   -376,   -360,   -280,   -264,   -312,   -296, 
	  -472,   -456,   -504,   -488,   -408,   -392,   -440,   -424, 
	   -88,    -72,   -120,   -104,    -24,     -8,    -56,    -40, 
	  -216,   -200,   -248,   -232,   -152,   -136,   -184,   -168, 
	 -1376,  -1312,  -1504,  -1440,  -1120,  -1056,  -1248,  -1184, 
	 -1888,  -1824,  -2016,  -1952,  -1632,  -1568,  -1760,  -1696, 
	  -688,   -656,   -752,   -720,   -560,   -528,   -624,   -592, 
	  -944,   -912,  -1008,   -976,   -816,   -784,   -880,   -848, 
	  5504,   5248,   6016,   5760,   4480,   4224,   4992,   4736, 
	  7552,   7296,   8064,   7808,   6528,   6272,   7040,   6784, 
	  2752,   2624,   3008,   2880,   2240,   2112,   2496,   2368, 
	  3776,   3648,   4032,   3904,   3264,   3136,   3520,   3392, 
	 22016,  20992,  24064,  23040,  17920,  16896,  19968,  18944, 
	 30208,  29184,  32256,  31232,  26112,  25088,  28160,  27136, 
	 11008,  10496,  12032,  11520,   8960,   8448,   9984,   9472, 
	 15104,  14592,  16128,  15616,  13056,  12544,  14080,  13568, 
	   344,    328,    376,    360,    280,    264,    312,    296, 
	   472,    456,    504,    488,    408,    392,    440,    424, 
	    88,     72,    120,    104,     24,      8,     56,     40, 
	   216,    200,    248,    232,    152,    136,    184,    168, 
	  1376,   1312,   1504,   1440,   1120,   1056,   1248,   1184, 
	  1888,   1824,   2016,   1952,   1632,   1568,   1760,   1696, 
	   688,    656,    752,    720,    560,    528,    624,    592, 
	   944,    912,   1008,    976,    816,    784,    880,    848, 
    };

/*! \brief Codec for 8-bit A-Law encoded data
 *  \param data		  pointer to audio data
 *  \param len		  number of bytes of data
 *  \param nChans	  number of channels
 *  \param bitsPerSample  number of bits per channel
 *  \param freq		  sample frequency
 *  \return		  data buffer with decoded audio
 */
BufferData_t *SML3D_ALawCodec (void *data, size_t len, int nChans, int bitsPerSample, float freq)
{
    int16_t *dst = (int16_t *)malloc(2 * len);
    BufferData_t *buf = NewBufferData (dst, 2*len, nChans, bitsPerSample, freq);

    if (buf != 0) {
      // convert to raw encoding
	int8_t *dp = (int8_t *)data;
	for (size_t i = 0;  i < len;  i++) {
	    dst[i] = ALaw2Linear[dp[i]];
	}
    }
    else if (dst != 0)
	free (dst);

    return buf;
}

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0