OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [mp3/] [sw/] [mad-xess/] [audio.c] - Rev 1774

Go to most recent revision | Compare with Previous | Blame | View Log

/*
 * mad - MPEG audio decoder
 * Copyright (C) 2000-2001 Robert Leslie
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * $Id: audio.c,v 1.3 2001-11-06 17:01:07 simons Exp $
 */
 
# ifdef HAVE_CONFIG_H
#  include "config.h"
# endif
 
# include "audio.h"
# include "mad.h"
 
#ifndef EMBED
# include <string.h>
# include <stdio.h>
extern FILE *fo;
int printf(char *fmt, ...);
#endif
 
char const *audio_error;
 
static mad_fixed_t left_err, right_err;
 
#define AUDIO_DBG 	0 
 
#if AUDIO_DBG
//unsigned short wave_dump[(0x40000/2)];
//int wave_seg_index[0x10000];
int wave_seg_nb = 0;
int wave_index = 0;
#endif
 
/*
 * NAME:	audio_linear_dither()
 * DESCRIPTION:	generic linear sample quantize and dither routine
 */
inline
signed long audio_linear_dither(unsigned int bits, mad_fixed_t sample,
				mad_fixed_t *error, struct audio_stats *stats)
{
  mad_fixed_t quantized;
 
  /* dither */
  sample += *error;
 
# if 1
  /* clip */
  quantized = sample;
  if (sample >= stats->peak_sample) {
    if (sample >= MAD_F_ONE) {
      quantized = MAD_F_ONE - 1;
      ++stats->clipped_samples;
      if (sample - quantized > stats->peak_clipping &&
	  mad_f_abs(*error) < (MAD_F_ONE >> (MAD_F_FRACBITS + 1 - bits)))
	stats->peak_clipping = sample - quantized;
    }
    stats->peak_sample = quantized;
  }
  else if (sample < -stats->peak_sample) {
    if (sample < -MAD_F_ONE) {
      quantized = -MAD_F_ONE;
      ++stats->clipped_samples;
      if (quantized - sample > stats->peak_clipping &&
	  mad_f_abs(*error) < (MAD_F_ONE >> (MAD_F_FRACBITS + 1 - bits)))
	stats->peak_clipping = quantized - sample;
    }
    stats->peak_sample = -quantized;
  }
# else
  /* clip */
  quantized = sample;
  if (sample >= MAD_F_ONE)
    quantized = MAD_F_ONE - 1;
  else if (sample < -MAD_F_ONE)
    quantized = -MAD_F_ONE;
# endif
 
  /* quantize */
  quantized &= ~((1L << (MAD_F_FRACBITS + 1 - bits)) - 1);
 
  /* error */
  *error = sample - quantized;
 
  /* scale */
  return quantized >> (MAD_F_FRACBITS + 1 - bits);
}
 
 
static struct audio_stats stats;
 
/*
 * NAME:	audio_pcm_s16le()
 * DESCRIPTION:	write a block of signed 16-bit little-endian PCM samples
 */
unsigned int audio_pcm_s16le(unsigned char *data, unsigned int nsamples,
			     mad_fixed_t const *left, mad_fixed_t const *right)
{
  unsigned int len;
  register signed int sample0, sample1;
 
  len = nsamples;
#if AUDIO_DBG
//  wave_seg_index[wave_seg_nb] = wave_index;
//  wave_seg_nb++;
report(wave_index);  
#endif
 
  while (len--) {
    sample0 = audio_linear_dither(16, *left++,  &left_err,  &stats);
    sample1 = audio_linear_dither(16, *right++, &right_err, &stats);
 
#ifdef EMBED
#ifdef OR1K
#ifndef OR1K_SIM
    *(volatile unsigned short *)0x40000000 = sample0;
//    *(volatile unsigned long *)0x40000000 = sample0;
//    *(volatile unsigned long *)0x40000000 = sample1;
//    *(volatile unsigned long *)0x40000000 = sample1;
 
#if AUDIO_DBG
//    wave_dump[wave_index] = (unsigned short)sample0;
    wave_index++;
//    wave_dump[wave_index] = (unsigned short)sample1;
    wave_index++;
#endif
 
#else
//    asm volatile("l.mtspr r0,%0,0x01234" : : "r" (sample0 | (sample1 << 16)));
    asm volatile("l.mtspr r0,%0,0x0FFFE" : : "r" (sample0 >> 0));
    asm volatile("l.mtspr r0,%0,0x0FFFE" : : "r" (sample0 >> 8));
    asm volatile("l.mtspr r0,%0,0x0FFFE" : : "r" (sample1 >> 0));
    asm volatile("l.mtspr r0,%0,0x0FFFE" : : "r" (sample1 >> 8));
#endif
#else
    printf("l.mtspr (0x0000FFFE) <- %x\n", (sample0 >> 0));
    printf("l.mtspr (0x0000FFFE) <- %x\n", (sample0 >> 8));
    printf("l.mtspr (0x0000FFFE) <- %x\n", (sample1 >> 0));
    printf("l.mtspr (0x0000FFFE) <- %x\n", (sample1 >> 8));
#endif
#else
    data[0] = sample0 >> 0;
    data[1] = sample0 >> 8;
    data[2] = sample1 >> 0;
    data[3] = sample1 >> 8;
    if (fo) {
      fputc (data[0], fo);
      fputc (data[1], fo);
      fputc (data[2], fo);
      fputc (data[3], fo);
    }
    data += 4;
#endif
  }
  return nsamples * 2 * 2;
}
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.