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

Subversion Repositories or1k

[/] [or1k/] [tags/] [first/] [mp3/] [sw/] [mad-xess/] [audio.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 266 lampret
/*
2
 * mad - MPEG audio decoder
3
 * Copyright (C) 2000-2001 Robert Leslie
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
 *
19
 * $Id: audio.c,v 1.1.1.1 2001-11-04 19:00:22 lampret Exp $
20
 */
21
 
22
# ifdef HAVE_CONFIG_H
23
#  include "config.h"
24
# endif
25
 
26
# include "audio.h"
27
# include "mad.h"
28
 
29
#ifndef EMBED
30
# include <string.h>
31
# include <stdio.h>
32
extern FILE *fo;
33
int printf(char *fmt, ...);
34
#endif
35
 
36
char const *audio_error;
37
 
38
static mad_fixed_t left_err, right_err;
39
 
40
#define AUDIO_DBG       0 
41
 
42
#if AUDIO_DBG
43
//unsigned short wave_dump[(0x40000/2)];
44
//int wave_seg_index[0x10000];
45
int wave_seg_nb = 0;
46
int wave_index = 0;
47
#endif
48
 
49
/*
50
 * NAME:        audio_linear_dither()
51
 * DESCRIPTION: generic linear sample quantize and dither routine
52
 */
53
inline
54
signed long audio_linear_dither(unsigned int bits, mad_fixed_t sample,
55
                                mad_fixed_t *error, struct audio_stats *stats)
56
{
57
  mad_fixed_t quantized;
58
 
59
  /* dither */
60
  sample += *error;
61
 
62
# if 1
63
  /* clip */
64
  quantized = sample;
65
  if (sample >= stats->peak_sample) {
66
    if (sample >= MAD_F_ONE) {
67
      quantized = MAD_F_ONE - 1;
68
      ++stats->clipped_samples;
69
      if (sample - quantized > stats->peak_clipping &&
70
          mad_f_abs(*error) < (MAD_F_ONE >> (MAD_F_FRACBITS + 1 - bits)))
71
        stats->peak_clipping = sample - quantized;
72
    }
73
    stats->peak_sample = quantized;
74
  }
75
  else if (sample < -stats->peak_sample) {
76
    if (sample < -MAD_F_ONE) {
77
      quantized = -MAD_F_ONE;
78
      ++stats->clipped_samples;
79
      if (quantized - sample > stats->peak_clipping &&
80
          mad_f_abs(*error) < (MAD_F_ONE >> (MAD_F_FRACBITS + 1 - bits)))
81
        stats->peak_clipping = quantized - sample;
82
    }
83
    stats->peak_sample = -quantized;
84
  }
85
# else
86
  /* clip */
87
  quantized = sample;
88
  if (sample >= MAD_F_ONE)
89
    quantized = MAD_F_ONE - 1;
90
  else if (sample < -MAD_F_ONE)
91
    quantized = -MAD_F_ONE;
92
# endif
93
 
94
  /* quantize */
95
  quantized &= ~((1L << (MAD_F_FRACBITS + 1 - bits)) - 1);
96
 
97
  /* error */
98
  *error = sample - quantized;
99
 
100
  /* scale */
101
  return quantized >> (MAD_F_FRACBITS + 1 - bits);
102
}
103
 
104
 
105
static struct audio_stats stats;
106
 
107
/*
108
 * NAME:        audio_pcm_s16le()
109
 * DESCRIPTION: write a block of signed 16-bit little-endian PCM samples
110
 */
111
unsigned int audio_pcm_s16le(unsigned char *data, unsigned int nsamples,
112
                             mad_fixed_t const *left, mad_fixed_t const *right)
113
{
114
  unsigned int len;
115
  register signed int sample0, sample1;
116
 
117
  len = nsamples;
118
#if AUDIO_DBG
119
//  wave_seg_index[wave_seg_nb] = wave_index;
120
//  wave_seg_nb++;
121
report(wave_index);
122
#endif
123
 
124
  while (len--) {
125
    sample0 = audio_linear_dither(16, *left++,  &left_err,  &stats);
126
    sample1 = audio_linear_dither(16, *right++, &right_err, &stats);
127
 
128
#ifdef EMBED
129
#ifdef OR1K
130
#if 1
131
    *(volatile unsigned short *)0x40000000 = sample0;
132
//    *(volatile unsigned long *)0x40000000 = sample0;
133
//    *(volatile unsigned long *)0x40000000 = sample1;
134
//    *(volatile unsigned long *)0x40000000 = sample1;
135
 
136
#if AUDIO_DBG
137
//    wave_dump[wave_index] = (unsigned short)sample0;
138
    wave_index++;
139
//    wave_dump[wave_index] = (unsigned short)sample1;
140
    wave_index++;
141
#endif
142
 
143
#else
144
//    asm volatile("l.mtspr r0,%0,0x01234" : : "r" (sample0 | (sample1 << 16)));
145
    asm volatile("l.mtspr r0,%0,0x0FFFE" : : "r" (sample0 >> 0));
146
    asm volatile("l.mtspr r0,%0,0x0FFFE" : : "r" (sample0 >> 8));
147
    asm volatile("l.mtspr r0,%0,0x0FFFE" : : "r" (sample1 >> 0));
148
    asm volatile("l.mtspr r0,%0,0x0FFFE" : : "r" (sample1 >> 8));
149
#endif
150
#else
151
    printf("l.mtspr (0x0000FFFE) <- %x\n", (sample0 >> 0));
152
    printf("l.mtspr (0x0000FFFE) <- %x\n", (sample0 >> 8));
153
    printf("l.mtspr (0x0000FFFE) <- %x\n", (sample1 >> 0));
154
    printf("l.mtspr (0x0000FFFE) <- %x\n", (sample1 >> 8));
155
#endif
156
#else
157
    data[0] = sample0 >> 0;
158
    data[1] = sample0 >> 8;
159
    data[2] = sample1 >> 0;
160
    data[3] = sample1 >> 8;
161
    if (fo) {
162
      fputc (data[0], fo);
163
      fputc (data[1], fo);
164
      fputc (data[2], fo);
165
      fputc (data[3], fo);
166
    }
167
    data += 4;
168
#endif
169
  }
170
  return nsamples * 2 * 2;
171
}

powered by: WebSVN 2.1.0

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