3
$Id: arts_a.cpp,v 1.12 2001/03/24 09:13:57 wester Exp $
5
TiMidity -- Experimental MIDI to WAVE converter
6
Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
8
This program is free software; you can redistribute it and/or modify
9
it under the terms of the GNU General Public License as published by
10
the Free Software Foundation; either version 2 of the License, or
11
(at your option) any later version.
13
This program is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
GNU General Public License for more details.
18
You should have received a copy of the GNU General Public License
19
along with this program; if not, write to the Free Software
20
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24
Functions to play sound on the VoxWare audio driver (Linux or FreeBSD)
41
static int open_output(void); /* 0=success, 1=warning, -1=fatal error */
42
static void close_output(void);
43
static void output_data(int32 *buf, uint32 count);
44
static int driver_output_data(unsigned char *buf, uint32 count);
45
static void flush_output(void);
46
static void purge_output(void);
47
static int output_count(uint32 ct);
49
static arts_stream_t stream;
50
static int server_buffer;
52
/* export the playback mode */
55
#define dpm arts_play_mode
58
DEFAULT_RATE, PE_16BIT|PE_SIGNED,
60
{0}, /* default: get all the buffer fragments you can */
72
/*************************************************************************/
73
/* We currently only honor the PE_MONO bit, the sample rate, and the
74
number of buffer fragments. We try 16-bit signed data first, and
75
then 8-bit unsigned if it fails. If you have a sound device that
76
can't handle either, let me know. */
78
static int output_count(uint32 ct)
80
extern int b_out_count();
82
int bytes_written = b_out_count();
83
int bytes_buffered = arts_stream_get(stream, ARTS_P_BUFFER_SIZE)
84
- arts_stream_get(stream, ARTS_P_BUFFER_SPACE)
85
+ server_buffer; /* see comment in _open */
86
int samples = bytes_written - bytes_buffered;
90
if (!(dpm.encoding & PE_MONO)) samples >>= 1;
91
if (dpm.encoding & PE_16BIT) samples >>= 1;
95
static int driver_output_data(unsigned char *buf, uint32 count)
97
return arts_write(stream,buf,count);
100
static void output_data(int32 *buf, uint32 count)
104
if (!(dpm.encoding & PE_MONO)) count*=2; /* Stereo samples */
108
if (dpm.encoding & PE_16BIT)
110
/* Convert data to signed 16-bit PCM */
111
s32tos16(buf, count);
116
/* Convert to 8-bit unsigned and write out. */
121
b_out(dpm.id_character, dpm.fd, (int *)buf, ocount);
125
static void close_output(void)
127
arts_close_stream(stream);
131
static void flush_output(void)
136
static void purge_output(void)
138
b_out(dpm.id_character, dpm.fd, 0, -1);
141
static int open_output(void) /* 0=success, 1=warning, -1=fatal error */
143
int sample_width, channels, rate;
149
fprintf(stderr, "aRts init failed: %s\n", arts_error_text(rc));
153
/* They can't mean these */
154
dpm.encoding &= ~(PE_ULAW|PE_BYTESWAP);
156
/* Set sample width to whichever the user wants. */
158
sample_width=(dpm.encoding & PE_16BIT) ? LE_LONG(16) : LE_LONG(8);
160
if (dpm.encoding & PE_16BIT)
161
dpm.encoding |= PE_SIGNED;
163
dpm.encoding &= ~PE_SIGNED;
166
/* Try stereo or mono, whichever the user wants. */
168
channels=(dpm.encoding & PE_MONO) ? 1 : 2;
170
/* Set the sample rate */
174
stream = arts_play_stream(rate, sample_width, channels, "artsctest");
176
arts_stream_set (stream, ARTS_P_BLOCKING, 0);
179
* I am not sure if its wise to include the server buffer in our
180
* output sample calculation. While including will give a more realistic
181
* idea of the position we are playing right now (and thus a better
182
* ability to synchronize with the display), it will also give the
183
* certainity "oh well, no worries, there are yet 70kb buffered".
185
* Well, they are, but if 64kb of these are buffered on the server,
186
* dropout will occur after 6kb anyways.
188
server_buffer = arts_stream_get(stream, ARTS_P_SERVER_LATENCY) *
189
rate * (sample_width/8) * channels / 1000;