source: abuse/tags/pd/imlib/port/aix/aix_sdrv.c @ 49

Last change on this file since 49 was 49, checked in by Sam Hocevar, 11 years ago
  • Imported original public domain release, for future reference.
  • Property svn:keywords set to Id
File size: 8.3 KB
Line 
1/*
2
3AIX UMS sound module.
4
5Biggest weirdo thing in here besides the include "gen_drv.c" (legacy)
6is that there is a bug in the AIX UMS sound support.  UMS won't play
7sound unless there are at least 8k (?) samples submitted.  Because this
8is almost a second when playing 8-bit 11kHz mono sound, the latency
9would kill the usefulness.  So the sound driver plays at 44kHz in
1016-bit stereo simply so that it can submit 8k chunks without hurting
11the sound latency.
12
13Seeing as how we were 16-bit, gen_drv.c was modified to support 13-bit
14mixing instead of 8-bit.  The clip was deferred until the output step
15to avoid an extra pass over the 13-bit buffer.
16
17*/
18
19#include <strings.h>
20#include <sys/ipc.h>
21#include <sys/shm.h>
22#include <signal.h>
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26#include <fcntl.h>
27#include <unistd.h>
28#include <sys/types.h>
29#include <sys/time.h>
30#include <sys/ioctl.h>
31#include <sys/types.h>
32#include <sys/stat.h>
33#include <sys/select.h>
34
35#include <UMSAudioDevice.h>
36
37void output_samples(short *buf);
38void sound_uninit();
39int sound_init();
40
41#define BUF_SIZE 512
42
43static UMSAudioDevice audio_device;
44static UMSAudioTypes_Buffer output_buffer;
45static Environment *audio_env;
46static int output_buffer_samples;
47static float usecs_per_samplepair;
48static int samplepair_latency;
49static short *output_buffer_data;
50static int last_sample;
51static char str[1024];
52
53#include "gen_drv.c"
54
55void output_samples(short *buf)
56{
57
58        long samplepairs_written;
59        long samplepairs_en_route;
60        int i;
61        int delta;
62        int d_prev;
63        int d_next;
64
65        output_buffer._length = output_buffer._maximum;
66
67// translate 13-bit mono 11kHz (1k) output buffer to linearly interpolated
68// 16-bit stereo 44kHz output buffer (8k).  for smooth transition between
69// buffers, first sample must be remembered from the last buffer.
70
71        d_prev = last_sample;
72
73        d_next = buf[0] << 3;
74        if (d_next < -32768) d_next = -32768;
75        else if (d_next > 32767) d_next = 32767;
76
77        delta = (d_next - d_prev) >> 2;
78        output_buffer_data[0] = d_prev;
79        output_buffer_data[2] = output_buffer_data[0] + delta;
80        output_buffer_data[4] = output_buffer_data[2] + delta;
81        output_buffer_data[6] = output_buffer_data[4] + delta;
82        output_buffer_data[1] = output_buffer_data[0];
83        output_buffer_data[3] = output_buffer_data[2];
84        output_buffer_data[5] = output_buffer_data[4];
85        output_buffer_data[7] = output_buffer_data[6];
86
87        d_prev = d_next;
88
89        for (i=1 ; i<BUF_SIZE ; i++)
90        {
91
92                d_next = buf[i] << 3;
93                if (d_next < -32768) d_next = -32768;
94                else if (d_next > 32767) d_next = 32767;
95
96                delta = (d_next - d_prev)>>2;
97                output_buffer_data[i*8] = d_prev;
98                output_buffer_data[i*8+2] = output_buffer_data[i*8] + delta;
99                output_buffer_data[i*8+4] = output_buffer_data[i*8+2] + delta;
100                output_buffer_data[i*8+6] = output_buffer_data[i*8+4] + delta;
101                output_buffer_data[i*8+1] = output_buffer_data[i*8];
102                output_buffer_data[i*8+3] = output_buffer_data[i*8+2];
103                output_buffer_data[i*8+5] = output_buffer_data[i*8+4];
104                output_buffer_data[i*8+7] = output_buffer_data[i*8+6];
105
106                d_prev = d_next;
107        }
108
109        last_sample = d_prev;
110
111// an essentially non-blocking write()
112        UMSAudioDevice_write(audio_device, audio_env, &output_buffer,
113                output_buffer_samples, &samplepairs_written);
114
115// simulate a blocking write() with usleep()
116        UMSAudioDevice_write_buff_used(audio_device, audio_env,
117                &samplepairs_en_route);
118        if (samplepairs_en_route > samplepair_latency)
119                usleep((int) ((samplepairs_en_route - samplepair_latency)
120                * usecs_per_samplepair));
121
122}
123
124void sound_uninit()
125{
126        UMSAudioDevice_play_remaining_data(audio_device, audio_env, TRUE);
127        UMSAudioDevice_stop(audio_device, audio_env);
128        UMSAudioDevice_close(audio_device, audio_env);
129}
130
131char *newpaths[] =
132{
133        "bin",
134        "dt/bin",
135        "speech/speech_reco/bin",
136        "Demos/speech_reco/bin",
137        "Demos/tts/bin"
138};
139
140char *newlibpaths[] =
141{
142        "lib",
143        "speech/speech_reco/lib",
144        "Demos/tts/lib"
145};
146
147void run_ums(void)
148{
149        char *path, *u;
150        int i;
151
152        if (!getenv("SOMBASE"))
153                putenv("SOMBASE=/usr/lpp/som");
154        fprintf(stderr, "SOMBASE=%s\n", getenv("SOMBASE"));
155        if (!getenv("UMSDIR"))
156                putenv("UMSDIR=/usr/lpp/UMS");
157        fprintf(stderr, "UMSDIR=%s\n", getenv("UMSDIR"));
158        sprintf(str, "PATH=");
159        path = getenv("PATH");
160        if (!path || *path==0) path=".";
161        strcat(str, path);
162        for (i=0 ; i<5 ; i++)
163        {
164                sprintf(str+512, "%s/%s", getenv("UMSDIR"), newpaths[i]);
165                fprintf(stderr, "str+512=[%s]\n", str+512);
166                if (!strstr(path, str+512))
167                {
168                        strcat(str, ":");
169                        strcat(str, str+512);
170                        fprintf(stderr, "str=[%s]\n", str);
171                }
172        }
173        putenv(str);
174        fprintf(stderr, "PATH=%s\n", getenv("PATH"));
175
176        sprintf(str, "LIBPATH=");
177        path = getenv("LIBPATH");
178        if (!path || *path==0) path=".";
179        fprintf(stderr, "[[%s]]\n", path);
180        strcat(str, path);
181        if (!strstr(path, "/usr/lib"))
182                strcat(str, ":/usr/lib");
183        sprintf(str+512, "%s/lib", getenv("SOMBASE"));
184        if (!strstr(path, str+512))
185        {
186                strcat(str, ":");
187                strcat(str, str+512);
188        }
189        for (i=0 ; i<3 ; i++)
190        {
191                sprintf(str+512, "%s/%s", getenv("UMSDIR"), newlibpaths[i]);
192                if (!strstr(path, str+512))
193                {
194                        strcat(str, ":");
195                        strcat(str, str+512);
196                }
197        }
198        putenv(str);
199        fprintf(stderr, "LIBPATH=%s\n", getenv("LIBPATH"));
200
201        sprintf(str, "NLSPATH=");
202        path = getenv("NLSPATH");
203        if (!path || *path == 0) path=".";
204        strcat(str, path);
205        sprintf(str+512, "%s/msg/%%N", getenv("SOMBASE"));
206        if (!strstr(path, str+512))
207        {
208                strcat(str, ":");
209                strcat(str, str+512);
210        }
211        putenv(str);
212        fprintf(stderr, "NLSPATH=%s\n", getenv("NLSPATH"));
213
214        sprintf(str, "SOMIR=");
215        path = getenv("SOMIR");
216        if (!path || *path == 0) path=".";
217        strcat(str, path);
218        sprintf(str+512, "%s/etc/UMS.ir", getenv("UMSDIR"));
219        if (!strstr(path, str+512))
220        {
221                strcat(str, ":");
222                strcat(str, str+512);
223        }
224        sprintf(str+512, "%s/etc/som.ir", getenv("UMSDIR"));
225        if (!strstr(path, str+512))
226        {
227                strcat(str, ":");
228                strcat(str, str+512);
229        }
230        putenv(str);
231        fprintf(stderr, "SOMIR=%s\n", getenv("SOMIR"));
232        putenv("MALLOCTYPE=");
233}
234
235int sound_init()
236{
237
238        UMSAudioDeviceMClass audio_device_class;
239        char *alias;
240        long flags;
241        UMSAudioDeviceMClass_ErrorCode audio_device_class_error;
242        char *error_string;
243        char *audio_formats_alias;
244        char *audio_inputs_alias;
245        char *audio_outputs_alias;
246        int bits_per_sample;
247        long out_rate;
248        int channels;
249        long left_gain;
250        long right_gain;
251        char *sl;
252
253//      run_ums();
254
255        audio_env = somGetGlobalEnvironment();
256
257        audio_device_class = UMSAudioDeviceNewClass(UMSAudioDevice_MajorVersion,
258                UMSAudioDevice_MinorVersion);
259    if (audio_device_class == NULL)
260        {
261        fprintf(stderr, "sound driver: Can't create AudioDeviceMClass metaclass\n");
262        return 0;
263        }
264
265    alias = "Audio";
266    flags = UMSAudioDevice_BlockingIO;
267
268        audio_device = UMSAudioDeviceMClass_make_by_alias(audio_device_class,
269                audio_env, alias, "PLAY", flags, &audio_device_class_error,
270                &error_string, &audio_formats_alias, &audio_inputs_alias,
271                &audio_outputs_alias);
272
273    if (audio_device == NULL)
274        {
275        fprintf(stderr, "sound driver : Can't create audio device object\n");
276        return 0;
277        }
278
279        channels = 2;
280        bits_per_sample = 16;
281
282        UMSAudioDevice_set_sample_rate(audio_device, audio_env, 44100, &out_rate);
283        UMSAudioDevice_set_bits_per_sample(audio_device, audio_env,
284                bits_per_sample);
285        UMSAudioDevice_set_number_of_channels(audio_device, audio_env, channels);
286
287        if (out_rate != 44100)
288        {
289                fprintf(stderr, "sound driver : Doesn't support 44.1kHz\n");
290                return 0;
291        }
292
293    UMSAudioDevice_set_audio_format_type(audio_device, audio_env, "PCM");
294    UMSAudioDevice_set_byte_order(audio_device, audio_env, "MSB");
295    UMSAudioDevice_set_number_format(audio_device, audio_env,
296                "TWOS_COMPLEMENT");
297        UMSAudioDevice_set_volume(audio_device, audio_env, 100);
298        UMSAudioDevice_set_balance(audio_device, audio_env, 0);
299
300        output_buffer_samples = BUF_SIZE * 4;
301        UMSAudioDevice_set_time_format(audio_device, audio_env,
302                UMSAudioTypes_Samples);
303
304        left_gain = right_gain = 100;
305        UMSAudioDevice_enable_output(audio_device, audio_env, "INTERNAL_SPEAKER",
306                &left_gain, &right_gain);
307        left_gain = right_gain = 100;
308        UMSAudioDevice_enable_output(audio_device, audio_env, "LINE_OUT",
309                &left_gain, &right_gain);
310
311        UMSAudioDevice_initialize(audio_device, audio_env);
312        UMSAudioDevice_start(audio_device, audio_env);
313
314        output_buffer._maximum = BUF_SIZE*8*2;
315        output_buffer_data = (short *) malloc(output_buffer._maximum);
316        output_buffer._buffer = (octet *) output_buffer_data;
317
318        usecs_per_samplepair = 1000000.0 / out_rate;
319
320        samplepair_latency = 1500;
321        sl = getenv("SAMPLEPAIR_LATENCY");
322        if (sl) samplepair_latency = atoi(sl);
323
324        last_sample = 0;
325
326        return 1;
327
328}
329
330
Note: See TracBrowser for help on using the repository browser.