root/ocaml-remix/trunk/oss_impl.c

Revision 529, 2.5 kB (checked in by shans, 4 years ago)

Replacing sound implementation - WAS ocaml int arrays, IS native float
arrays. This has not yet been completely been debugged!

Line 
1 #include <sys/soundcard.h>
2 #include <stdlib.h>
3 #include <sys/types.h>
4 #include <sys/stat.h>
5 #include <sys/ioctl.h>
6 #include <fcntl.h>
7 #include <unistd.h>
8 #include <stdio.h>
9
10 #include <caml/alloc.h>
11 #include <caml/callback.h>
12 #include <caml/fail.h>
13 #include <caml/memory.h>
14 #include <caml/misc.h>
15 #include <caml/mlvalues.h>
16
17 #define SND_LOG 0
18
19 typedef struct SoundDevice_t {
20   int     device;
21 #if SND_LOG
22   FILE  * snd_log;
23 #endif
24 } SoundDevice;
25
26 SoundDevice *sound_open(void) {
27   SoundDevice * dev = malloc(sizeof(SoundDevice));
28   int           tmp = AFMT_S16_LE;
29
30   dev->device = open("/dev/dsp", O_WRONLY, 0);
31   ioctl(dev->device, SNDCTL_DSP_SETFMT, &tmp);
32 #if SND_LOG
33   dev->snd_log = fopen("snd_log.raw", "a");
34 #endif
35   return dev;
36 }
37
38 void sound_set_parms(SoundDevice *dev, int channels, int rate) {
39   ioctl(dev->device, SNDCTL_DSP_CHANNELS, &channels);
40   ioctl(dev->device, SNDCTL_DSP_SPEED, &rate);
41 }
42
43 void sound_write(SoundDevice *dev, short *data, int samples) {
44
45 #if SND_LOG
46   fwrite(data, sizeof(short), samples, dev->snd_log);
47 #endif
48   write(dev->device, data, samples * sizeof(short));
49  
50 }
51
52 void sound_close(SoundDevice *dev) {
53   close(dev->device);
54 #if SND_LOG
55   fclose(dev->snd_log);
56 #endif
57   free(dev);
58 }
59
60 #define Store_c_field(block,offset,x) (Field(block,offset)=(value)x)
61
62 CAMLprim c_ex_sound_open(value ml_unit)
63 {
64   CAMLparam1(ml_unit);
65
66   SoundDevice *result = sound_open();
67
68   CAMLlocal1(block);
69   block = alloc(1, Abstract_tag);
70   Store_c_field(block,0,(value)result);
71   CAMLreturn(block);
72 }
73
74 CAMLprim c_ex_sound_set_parms(value ml_dev, value ml_channels, value ml_rate) {
75  
76   CAMLparam3(ml_dev, ml_channels, ml_rate);
77
78   int channels, rate;
79   SoundDevice *dev;
80
81   channels=Int_val(ml_channels);
82   rate=Int_val(ml_rate);
83   dev = (SoundDevice *)Field(ml_dev, 0);
84
85   sound_set_parms(dev, channels, rate);
86
87   CAMLreturn(Val_unit);
88
89 }
90
91 CAMLprim c_ex_sound_write(value ml_dev, value ml_data, value ml_length) {
92
93   CAMLparam2(ml_dev, ml_data);
94
95   SoundDevice *dev;
96   int length;
97   int i;
98   short *data;
99   float *indata;
100
101   dev = (SoundDevice *)Field(ml_dev, 0);
102   length = Int_val(ml_length);
103   data = malloc(length * sizeof(short));
104   indata = ((float *)Field(ml_data, 1));
105  
106   for (i = 0; i < length; i++) {
107     data[i] = (short)(indata[i] * 32767);
108   }
109  
110   sound_write(dev, data, length);
111   free(data);
112
113   CAMLreturn(Val_unit);
114  
115 }
116
117 CAMLprim c_ex_sound_close(value ml_dev) {
118
119   CAMLparam1(ml_dev);
120
121   SoundDevice *dev;
122
123   dev = (SoundDevice *)Field(ml_dev, 0);
124   sound_close(dev);
125
126   CAMLreturn(Val_unit);
127 }
Note: See TracBrowser for help on using the browser.