~ubuntu-branches/ubuntu/lucid/mpg123/lucid

« back to all changes in this revision

Viewing changes to audio_aix.c

Tags: upstream-0.60
ImportĀ upstreamĀ versionĀ 0.60

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *  Driver for IBM RS/6000 with AIX Ultimedia Services
3
 
 * 
4
 
 *  Code by Juergen Schoew <juergen.schoew@unix-ag.org>
5
 
 *
6
 
 *          Tomas Oegren   <stric@acc.umu.se>
7
 
 *                         (code for audio_close delay)
8
 
 *
9
 
 *  Cleanups and testing by Niklas Edmundsson <nikke@ing.umu.se>
10
 
 *
11
 
 */
12
 
 
13
 
#include <stdio.h>
14
 
#include <unistd.h>
15
 
#include <stdlib.h>
16
 
 
17
 
#include <errno.h>
18
 
#include <fcntl.h>
19
 
#include <sys/audio.h>
20
 
#include <stropts.h>
21
 
#include <sys/types.h>
22
 
#include <sys/file.h>
23
 
#include <sys/stat.h>
24
 
#include <sys/param.h>
25
 
 
26
 
#include "mpg123.h"
27
 
 
28
 
/* use AUDIO_BSIZE to set the msec for audio buffering in Ultimedia library
29
 
 */
30
 
/* #define AUDIO_BSIZE AUDIO_IGNORE */
31
 
#define AUDIO_BSIZE 200
32
 
 
33
 
 
34
 
int audio_open(struct audio_info_struct *ai)
35
 
{
36
 
  audio_init ainit;
37
 
  int ret;
38
 
 
39
 
  if(!ai->device) {
40
 
    if(getenv("AUDIODEV")) {
41
 
      if(param.verbose > 1) 
42
 
         fprintf(stderr,"Using audio-device value from AUDIODEV environmentvariable!\n");
43
 
      ai->device = getenv("AUDIODEV");
44
 
      ai->fn = open(ai->device,O_WRONLY);
45
 
    }
46
 
    else {
47
 
      ai->device = "/dev/paud0/1";                   /* paud0 for PCI */
48
 
      ai->fn = open(ai->device,O_WRONLY);
49
 
      if ((ai->fn == -1) & (errno == ENOENT)) {
50
 
        ai->device = "/dev/baud0/1";                 /* baud0 for MCA */
51
 
        ai->fn = open(ai->device,O_WRONLY);
52
 
      }   
53
 
    }
54
 
  } else ai->fn = open(ai->device,O_WRONLY);
55
 
 
56
 
  if(ai->fn < 0){
57
 
     fprintf(stderr,"Can't open audio device!\n");
58
 
     return ai->fn;
59
 
  }
60
 
 
61
 
  /* Init to default values */
62
 
  memset ( & ainit, '\0', sizeof (ainit));
63
 
  ainit.srate            = 44100;
64
 
  ainit.channels         = 2;
65
 
  ainit.mode             = PCM;
66
 
  ainit.bits_per_sample  = 16;
67
 
  ainit.flags            = BIG_ENDIAN | TWOS_COMPLEMENT;
68
 
  ainit.operation        = PLAY;
69
 
  ainit.bsize            = AUDIO_BSIZE;
70
 
 
71
 
  ret = ioctl (ai->fn, AUDIO_INIT, & ainit);
72
 
  if (ret < 0)
73
 
     return ret;
74
 
  audio_reset_parameters(ai);
75
 
  return ai->fn;
76
 
}
77
 
 
78
 
int audio_reset_parameters(struct audio_info_struct *ai)
79
 
{
80
 
  audio_control  acontrol;
81
 
  audio_change   achange;
82
 
  audio_init     ainit;
83
 
  int ret;
84
 
 
85
 
  memset ( & achange, '\0', sizeof (achange));
86
 
  memset ( & acontrol, '\0', sizeof (acontrol));
87
 
  
88
 
  achange.balance        = 0x3fff0000;
89
 
  achange.balance_delay  = 0;
90
 
  achange.volume         = (long) (0x7fff << 16);
91
 
  achange.volume_delay   = 0;
92
 
  achange.input          = AUDIO_IGNORE;
93
 
  if (ai->output == -1) achange.output = INTERNAL_SPEAKER;
94
 
  else
95
 
  achange.output      = 0;
96
 
  if(ai->output & AUDIO_OUT_INTERNAL_SPEAKER)
97
 
     achange.output     |= INTERNAL_SPEAKER;
98
 
  if(ai->output & AUDIO_OUT_HEADPHONES)
99
 
     achange.output     |= EXTERNAL_SPEAKER;
100
 
  if(ai->output & AUDIO_OUT_LINE_OUT)
101
 
     achange.output     |= OUTPUT_1;
102
 
  if(ai->output == 0)
103
 
     achange.output      = AUDIO_IGNORE;
104
 
  achange.treble         = AUDIO_IGNORE;
105
 
  achange.bass          = AUDIO_IGNORE;
106
 
  achange.pitch          = AUDIO_IGNORE;
107
 
  achange.monitor        = AUDIO_IGNORE;
108
 
  achange.dev_info       = (char *) NULL;
109
 
 
110
 
  acontrol.ioctl_request = AUDIO_CHANGE;
111
 
  acontrol.position      = 0;
112
 
  acontrol.request_info  = (char *) & achange;
113
 
 
114
 
  ret = ioctl (ai->fn, AUDIO_CONTROL, & acontrol);
115
 
  if (ret < 0)
116
 
    return ret;
117
 
 
118
 
  /* Init Device for new values */
119
 
  if (ai->rate >0) {
120
 
    memset ( & ainit, '\0', sizeof (ainit));
121
 
    ainit.srate                 = audio_rate_best_match(ai);
122
 
    if (ai->channels > 0)
123
 
       ainit.channels          = ai->channels;
124
 
    else
125
 
      ainit.channels           = 1;
126
 
    switch (ai->format) {
127
 
      default :
128
 
        ainit.mode             = PCM;
129
 
        ainit.bits_per_sample  = 8;
130
 
        ainit.flags            = BIG_ENDIAN | TWOS_COMPLEMENT;
131
 
        break;
132
 
      case AUDIO_FORMAT_SIGNED_16:
133
 
        ainit.mode             = PCM;
134
 
        ainit.bits_per_sample  = 16;
135
 
        ainit.flags            = BIG_ENDIAN | TWOS_COMPLEMENT;
136
 
        break;
137
 
      case AUDIO_FORMAT_SIGNED_8:
138
 
        ainit.mode             = PCM;
139
 
        ainit.bits_per_sample  = 8;
140
 
        ainit.flags            = BIG_ENDIAN | TWOS_COMPLEMENT;
141
 
        break;
142
 
      case AUDIO_FORMAT_UNSIGNED_16:
143
 
        ainit.mode             = PCM;
144
 
        ainit.bits_per_sample  = 16;
145
 
        ainit.flags            = BIG_ENDIAN | TWOS_COMPLEMENT | SIGNED;
146
 
        break;
147
 
      case AUDIO_FORMAT_UNSIGNED_8:
148
 
        ainit.mode             = PCM;
149
 
        ainit.bits_per_sample  = 8;
150
 
        ainit.flags            = BIG_ENDIAN | TWOS_COMPLEMENT | SIGNED;
151
 
        break;
152
 
      case AUDIO_FORMAT_ULAW_8:
153
 
        ainit.mode             = MU_LAW;
154
 
        ainit.bits_per_sample  = 8;
155
 
        ainit.flags            = BIG_ENDIAN | TWOS_COMPLEMENT;
156
 
        break;
157
 
      case AUDIO_FORMAT_ALAW_8:
158
 
        ainit.mode             = A_LAW;
159
 
        ainit.bits_per_sample  = 8;
160
 
        ainit.flags            = BIG_ENDIAN | TWOS_COMPLEMENT;
161
 
        break;
162
 
    }
163
 
    ainit.operation            = PLAY;
164
 
    ainit.bsize                = AUDIO_BSIZE;
165
 
 
166
 
    ret = ioctl (ai->fn, AUDIO_INIT, & ainit);
167
 
    if (ret < 0) {
168
 
      fprintf(stderr,"Can't set new audio parameters!\n");
169
 
      return ret;
170
 
    }
171
 
  }
172
 
 
173
 
  acontrol.ioctl_request   = AUDIO_START;
174
 
  acontrol.request_info    = NULL;
175
 
  acontrol.position        = 0;
176
 
 
177
 
  ret = ioctl (ai->fn, AUDIO_CONTROL, & acontrol);
178
 
  if (ret < 0) {
179
 
    fprintf(stderr,"Can't reset audio!\n");
180
 
    return ret;
181
 
  }
182
 
  return 0;
183
 
}
184
 
 
185
 
int audio_rate_best_match(struct audio_info_struct *ai)
186
 
{
187
 
  static long valid [ ] = {  5510,  6620,  8000,  9600, 11025, 16000, 18900,
188
 
                            22050, 27420, 32000, 33075, 37800, 44100, 48000, 0 };
189
 
  int  i = 0;
190
 
  long best = 8000;
191
 
 
192
 
  if(!ai || ai->fn < 0 || ai->rate < 0) {
193
 
    return -1;
194
 
  } 
195
 
 
196
 
  while (valid [i])
197
 
  {
198
 
    if (abs(valid[i] - ai->rate) < abs(best - ai->rate))
199
 
    {
200
 
      best = valid [i];
201
 
    }
202
 
    i = i + 1;
203
 
  }
204
 
 
205
 
  ai->rate = best;
206
 
  return best;
207
 
}
208
 
 
209
 
int audio_set_rate(struct audio_info_struct *ai)
210
 
{
211
 
  return audio_reset_parameters(ai);
212
 
}
213
 
 
214
 
int audio_set_channels(struct audio_info_struct *ai)
215
 
{
216
 
  return audio_reset_parameters(ai);
217
 
}
218
 
 
219
 
int audio_set_format(struct audio_info_struct *ai)
220
 
{
221
 
  return audio_reset_parameters(ai);
222
 
}
223
 
 
224
 
int audio_get_formats(struct audio_info_struct *ai)
225
 
{
226
 
/* ULTIMEDIA DOCUMENTATION SAYS:
227
 
   The Ultimedia Audio Adapter supports fourteen sample rates you can use to
228
 
   capture and playback audio data. The rates are (in kHz): 5.51, 6.62, 8.0,
229
 
   9.6, 11.025, 16.0, 18.9, 22.050, 27.42, 32.0, 33.075, 37.8, 44.1, and 48.0.
230
 
   These rates are supported for mono and stereo PCM (8- and 16-bit), mu-law,
231
 
   and A-law. 
232
 
*/
233
 
 
234
 
  long rate;
235
 
  
236
 
  rate = ai->rate;
237
 
  audio_rate_best_match(ai);
238
 
  if (ai->rate == rate)
239
 
     return (AUDIO_FORMAT_SIGNED_16|AUDIO_FORMAT_UNSIGNED_16|
240
 
             AUDIO_FORMAT_UNSIGNED_8|AUDIO_FORMAT_SIGNED_8|
241
 
             AUDIO_FORMAT_ULAW_8|AUDIO_FORMAT_ALAW_8);
242
 
  else
243
 
    return 0;
244
 
}
245
 
 
246
 
int audio_play_samples(struct audio_info_struct *ai,unsigned char *buf,int len)
247
 
{
248
 
    return write(ai->fn,buf,len);
249
 
}
250
 
 
251
 
int audio_close(struct audio_info_struct *ai)
252
 
{
253
 
    audio_control acontrol;
254
 
    audio_buffer  abuffer;
255
 
    int           ret,i;
256
 
 
257
 
    /* Don't close the audio-device until it's played all its contents */
258
 
    memset ( & acontrol, '\0', sizeof ( acontrol ) );
259
 
    acontrol.request_info = &abuffer;
260
 
    acontrol.position = 0;
261
 
    i=50;   /* Don't do this forever on a bad day :-) */
262
 
    while (i-- > 0) {
263
 
            if ((ioctl(ai->fn, AUDIO_BUFFER, &acontrol))< 0) {
264
 
                    fprintf(stderr, "buffer read failed: %d\n", errno);
265
 
                    break;
266
 
            } else {
267
 
                    if (abuffer.flags <= 0)
268
 
                            break;
269
 
            }
270
 
            usleep(200000); /* sleep 0.2 sec */
271
 
    }
272
 
 
273
 
    memset ( & acontrol, '\0', sizeof ( acontrol ) );
274
 
    acontrol.ioctl_request = AUDIO_STOP;
275
 
    acontrol.request_info  = NULL;
276
 
    acontrol.position      = 0;
277
 
 
278
 
    ret = ioctl ( ai->fn, AUDIO_CONTROL, & acontrol );
279
 
    if (ret < 0)
280
 
       fprintf(stderr,"Can't close audio!\n");
281
 
 
282
 
    ret = close (ai->fn);
283
 
    if (ret < 0)
284
 
      fprintf(stderr,"Can't close audio!\n");
285
 
 
286
 
    return 0;
287
 
}