~ubuntu-branches/ubuntu/hoary/kdemultimedia/hoary

« back to all changes in this revision

Viewing changes to kmidi/esd_a.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Martin Schulze
  • Date: 2003-01-22 15:00:51 UTC
  • Revision ID: james.westby@ubuntu.com-20030122150051-uihwkdoxf15mi1tn
Tags: upstream-2.2.2
ImportĀ upstreamĀ versionĀ 2.2.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 
 
3
    TiMidity++ -- MIDI to WAVE converter and player
 
4
    Copyright (C) 1999 Masanao Izumo <mo@goice.co.jp>
 
5
    Copyright (C) 1995 Tuukka Toivonen <tt@cgs.fi>
 
6
 
 
7
    This program is free software; you can redistribute it and/or modify
 
8
    it under the terms of the GNU General Public License as published by
 
9
    the Free Software Foundation; either version 2 of the License, or
 
10
    (at your option) any later version.
 
11
 
 
12
    This program is distributed in the hope that it will be useful,
 
13
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
    GNU General Public License for more details.
 
16
 
 
17
    You should have received a copy of the GNU General Public License
 
18
    along with this program; if not, write to the Free Software
 
19
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
20
 
 
21
    esd_a.c by Avatar <avatar@deva.net>
 
22
    based on linux_a.c
 
23
 
 
24
    Functions to play sound through EsounD
 
25
*/
 
26
 
 
27
#ifdef AU_ESD
 
28
 
 
29
#ifdef ORIG_TIMPP
 
30
#ifdef HAVE_CONFIG_H
 
31
#include "config.h"
 
32
#endif /* HAVE_CONFIG_H */
 
33
#endif
 
34
 
 
35
#define _GNU_SOURCE
 
36
#include <stdio.h>
 
37
#include <unistd.h>
 
38
#include <fcntl.h>
 
39
 
 
40
#ifndef NO_STRING_H
 
41
#include <string.h>
 
42
#else
 
43
#include <strings.h>
 
44
#endif
 
45
#include <errno.h>
 
46
 
 
47
#include <esd.h>
 
48
 
 
49
#ifdef ORIG_TIMPP
 
50
#include "timidity.h"
 
51
#else
 
52
#include "config.h"
 
53
#endif
 
54
#include "common.h"
 
55
#include "output.h"
 
56
#include "controls.h"
 
57
#ifdef ORIG_TIMPP
 
58
#include "timer.h"
 
59
#endif
 
60
#include "instrum.h"
 
61
#include "playmidi.h"
 
62
#ifdef ORIG_TIMPP
 
63
#include "miditrace.h"
 
64
#endif
 
65
 
 
66
#ifdef ORIG_TIMPP
 
67
static int acntl(int request, void *arg);
 
68
#endif
 
69
static int open_output(void); /* 0=success, 1=warning, -1=fatal error */
 
70
static void close_output(void);
 
71
static void output_data(int32 *buf, uint32 count);
 
72
static int driver_output_data(unsigned char *buf, uint32 count);
 
73
static void flush_output(void);
 
74
static void purge_output(void);
 
75
static int output_count(uint32 ct);
 
76
 
 
77
/* export the playback mode */
 
78
 
 
79
#define dpm esd_play_mode
 
80
 
 
81
#ifdef ORIG_TIMPP
 
82
PlayMode dpm = {
 
83
    DEFAULT_RATE,
 
84
    PE_16BIT|PE_SIGNED,
 
85
    PF_PCM_STREAM|PF_CAN_TRACE|PF_BUFF_FRAGM_OPT,
 
86
    -1,
 
87
    {0}, /* default: get all the buffer fragments you can */
 
88
    "Enlightened sound daemon", 'e',
 
89
    "/dev/dsp",
 
90
    open_output,
 
91
    close_output,
 
92
    output_data,
 
93
    acntl
 
94
};
 
95
#else
 
96
PlayMode dpm = {
 
97
    DEFAULT_RATE,
 
98
    PE_16BIT|PE_SIGNED,
 
99
    -1,
 
100
    {0}, /* default: get all the buffer fragments you can */
 
101
    "Enlightened sound daemon", 'e',
 
102
    "/dev/dsp",
 
103
    open_output,
 
104
    close_output,
 
105
    output_data,
 
106
    driver_output_data,
 
107
    flush_output,
 
108
    purge_output,
 
109
    output_count
 
110
};
 
111
#endif
 
112
 
 
113
#define PE_ALAW         0x20
 
114
 
 
115
/*************************************************************************/
 
116
/* We currently only honor the PE_MONO bit, and the sample rate. */
 
117
 
 
118
static int open_output(void)
 
119
{
 
120
    int fd, /*tmp, i,*/ warnings = 0;
 
121
    /* int include_enc, exclude_enc; */
 
122
    esd_format_t esdformat;
 
123
 
 
124
#if 0
 
125
    include_enc = 0;
 
126
    exclude_enc = PE_ULAW|PE_ALAW|PE_BYTESWAP; /* They can't mean these */
 
127
    if(dpm.encoding & PE_16BIT)
 
128
        include_enc |= PE_SIGNED;
 
129
    else
 
130
        exclude_enc |= PE_SIGNED;
 
131
    dpm.encoding = validate_encoding(dpm.encoding, include_enc, exclude_enc);
 
132
#endif
 
133
 
 
134
    /* Open the audio device */
 
135
    esdformat = (dpm.encoding & PE_16BIT) ? ESD_BITS16 : ESD_BITS8;
 
136
    esdformat |= (dpm.encoding & PE_MONO) ? ESD_MONO : ESD_STEREO;
 
137
    fd = esd_play_stream_fallback(esdformat,dpm.rate,NULL,"timidity");
 
138
    if(fd < 0)
 
139
    {
 
140
        ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: %s",
 
141
                  dpm.name, strerror(errno));
 
142
        return -1;
 
143
    }
 
144
 
 
145
 
 
146
    dpm.fd = fd;
 
147
 
 
148
    return warnings;
 
149
}
 
150
 
 
151
static int driver_output_data(unsigned char *buf, uint32 count)
 
152
{
 
153
    return write(dpm.fd, buf, count);
 
154
}
 
155
 
 
156
#ifdef ORIG_TMPP
 
157
static int output_data(char *buf, uint32 count)
 
158
{
 
159
    int n;
 
160
 
 
161
    while(count > 0)
 
162
    {
 
163
        if((n = write(dpm.fd, buf, count)) == -1)
 
164
        {
 
165
            ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,
 
166
                      "%s: %s", dpm.name, strerror(errno));
 
167
            if(errno == EWOULDBLOCK)
 
168
            {
 
169
                /* It is possible to come here because of bug of the
 
170
                 * sound driver.
 
171
                 */
 
172
                continue;
 
173
            }
 
174
            return -1;
 
175
        }
 
176
        buf += n;
 
177
        count -= n;
 
178
    }
 
179
 
 
180
    return 0;
 
181
}
 
182
#endif
 
183
 
 
184
#ifndef ORIG_TIMPP
 
185
 
 
186
static int output_count(uint32 ct)
 
187
{
 
188
  int samples = -1;
 
189
  int samples_queued = 0, samples_sent = (int)ct;
 
190
  extern int b_out_count();
 
191
 
 
192
  samples = samples_sent = b_out_count();
 
193
 
 
194
  if (samples_sent) {
 
195
/* samples_queued is PM_REQ_GETFILLED */
 
196
#if 0
 
197
      if (snd_pcm_playback_status(handle, &playback_status) == 0)
 
198
        samples_queued = playback_status.queue;
 
199
#endif
 
200
      samples -= samples_queued;
 
201
  }
 
202
  if (!(dpm.encoding & PE_MONO)) samples >>= 1;
 
203
  if (dpm.encoding & PE_16BIT) samples >>= 1;
 
204
  return samples;
 
205
}
 
206
 
 
207
static void output_data(int32 *buf, uint32 count)
 
208
{
 
209
  int ocount;
 
210
 
 
211
  if (!(dpm.encoding & PE_MONO)) count*=2; /* Stereo samples */
 
212
  ocount = (int)count;
 
213
 
 
214
  if (ocount) {
 
215
    if (dpm.encoding & PE_16BIT)
 
216
      {
 
217
        /* Convert data to signed 16-bit PCM */
 
218
        s32tos16(buf, count);
 
219
        ocount *= 2;
 
220
      }
 
221
    else
 
222
      {
 
223
        /* Convert to 8-bit unsigned and write out. */
 
224
        s32tou8(buf, count);
 
225
      }
 
226
  }
 
227
 
 
228
  b_out(dpm.id_character, dpm.fd, (int *)buf, ocount);
 
229
}
 
230
 
 
231
 
 
232
static void flush_output(void)
 
233
{
 
234
  output_data(0, 0);
 
235
  esd_audio_flush();
 
236
}
 
237
 
 
238
static void purge_output(void)
 
239
{
 
240
  b_out(dpm.id_character, dpm.fd, 0, -1);
 
241
}
 
242
 
 
243
#endif
 
244
 
 
245
 
 
246
static void close_output(void)
 
247
{
 
248
    if(dpm.fd == -1)
 
249
        return;
 
250
    close(dpm.fd);
 
251
    dpm.fd = -1;
 
252
}
 
253
 
 
254
#ifdef ORIG_TIMPP
 
255
static int acntl(int request, void *arg)
 
256
{
 
257
    switch(request)
 
258
    {
 
259
      case PM_REQ_DISCARD:
 
260
        esd_audio_flush();
 
261
        return 0;
 
262
 
 
263
      case PM_REQ_RATE: {
 
264
          /* not implemented yet */
 
265
          break;
 
266
        }
 
267
    }
 
268
    return -1;
 
269
}
 
270
#endif
 
271
 
 
272
#endif /* AU_ESD */