Mercurial > mplayer.hg
comparison libao2/ao_jack.c @ 12662:05d46af5e2bf
JACK audio support through bio2jack by Kamil Strzelecki <esack@o2.pl>
author | alex |
---|---|
date | Fri, 25 Jun 2004 18:11:15 +0000 |
parents | |
children | b6d1267f189e |
comparison
equal
deleted
inserted
replaced
12661:31b3c61e53dd | 12662:05d46af5e2bf |
---|---|
1 /* | |
2 * ao_jack - JACK audio output driver for MPlayer | |
3 * | |
4 * Kamil Strzelecki < esack at browarek.net > | |
5 * | |
6 * This driver is distribuited under terms of GPL | |
7 * | |
8 * It uses bio2jack (http://bio2jack.sf.net/). | |
9 * | |
10 */ | |
11 | |
12 #include <stdio.h> | |
13 | |
14 #include "audio_out.h" | |
15 #include "audio_out_internal.h" | |
16 #include "afmt.h" | |
17 #include "../config.h" | |
18 #include "../mp_msg.h" | |
19 | |
20 //#include "bio2jack.h" | |
21 | |
22 static int driver = 0; | |
23 | |
24 //bio2jack stuff: | |
25 #define ERR_SUCCESS 0 | |
26 #define ERR_OPENING_JACK 1 | |
27 #define ERR_RATE_MISMATCH 2 | |
28 #define ERR_BYTES_PER_FRAME_INVALID 3 | |
29 enum status_enum { PLAYING, PAUSED, STOPPED, CLOSED, RESET }; | |
30 void JACK_Init(void); | |
31 int JACK_Open(int* deviceID, unsigned int bits_per_sample, unsigned long *rate, int channels); | |
32 int JACK_Close(int deviceID); /* return 0 for success */ | |
33 void JACK_Reset(int deviceID); /* free all buffered data and reset several values in the device */ | |
34 long JACK_Write(int deviceID, char *data, unsigned long bytes); /* returns the number of bytes written */ | |
35 long JACK_GetJackLatency(int deviceID); /* return the latency in milliseconds of jack */ | |
36 int JACK_SetState(int deviceID, enum status_enum state); /* playing, paused, stopped */ | |
37 int JACK_SetVolume(int deviceID, int left, int right); /* returns 0 on success */ | |
38 void JACK_GetVolume(int deviceID, int *left, int *right); | |
39 // | |
40 | |
41 | |
42 static ao_info_t info = | |
43 { | |
44 "JACK audio output", | |
45 "jack", | |
46 "Kamil Strzelecki <esack@browarek.net>", | |
47 "" | |
48 }; | |
49 | |
50 | |
51 LIBAO_EXTERN(jack) | |
52 | |
53 | |
54 static int control(int cmd, void *arg) | |
55 { | |
56 switch(cmd) { | |
57 case AOCONTROL_GET_VOLUME: | |
58 { | |
59 ao_control_vol_t *vol = (ao_control_vol_t *)arg; | |
60 int *l, *r; | |
61 | |
62 JACK_GetVolume(driver, l, r); | |
63 vol->left = (float )*l; | |
64 vol->right = (float )*r; | |
65 | |
66 return CONTROL_OK; | |
67 } | |
68 case AOCONTROL_SET_VOLUME: | |
69 { | |
70 ao_control_vol_t *vol = (ao_control_vol_t *)arg; | |
71 int l = (int )vol->left, | |
72 r = (int )vol->right, | |
73 err = 0; | |
74 | |
75 if((err = JACK_SetVolume(driver, l, r))) { | |
76 mp_msg(MSGT_AO, MSGL_ERR, | |
77 "AO: [Jack] Setting volume failed, error %d\n",err); | |
78 return CONTROL_ERROR; | |
79 } | |
80 | |
81 return CONTROL_OK; | |
82 } | |
83 } | |
84 | |
85 return(CONTROL_UNKNOWN); | |
86 } | |
87 | |
88 | |
89 static int init(int rate_hz, int channels, int format, int flags) | |
90 { | |
91 int err, m, frag_spec; | |
92 unsigned long rate; | |
93 unsigned int bits_per_sample; | |
94 | |
95 mp_msg(MSGT_AO, MSGL_INFO, "AO: [Jack] Initialising library.\n"); | |
96 JACK_Init(); | |
97 | |
98 switch (format) { | |
99 case AFMT_U8: | |
100 case AFMT_S8: | |
101 format = AFMT_U8; | |
102 bits_per_sample = 8; | |
103 m = 1; | |
104 break; | |
105 default: | |
106 format = AFMT_S16_LE; | |
107 bits_per_sample = 16; | |
108 m = 2; | |
109 break; | |
110 } | |
111 | |
112 rate = rate_hz; | |
113 | |
114 err = JACK_Open(&driver, bits_per_sample, &rate, channels); | |
115 | |
116 /* if sample rates doesn't match try to open device with jack's rate and | |
117 * let mplayer convert it (rate now contains that which jackd use) */ | |
118 if(err == ERR_RATE_MISMATCH) { | |
119 mp_msg(MSGT_AO, MSGL_INFO, | |
120 "AO: [Jack] Sample rate mismatch, trying to resample.\n"); | |
121 | |
122 err = JACK_Open(&driver, bits_per_sample, &rate, channels); | |
123 } | |
124 | |
125 /* any other error */ | |
126 if(err != ERR_SUCCESS) { | |
127 mp_msg(MSGT_AO, MSGL_ERR, | |
128 "AO: [Jack] JACK_Open() failed, error %d\n", err); | |
129 return 0; | |
130 } | |
131 | |
132 ao_data.format = format; | |
133 ao_data.channels = channels; | |
134 ao_data.samplerate = rate; | |
135 ao_data.bps = ( rate * channels * m ); | |
136 | |
137 mp_msg(MSGT_AO, MSGL_INFO, | |
138 "AO: [Jack] OK. I'm ready to go (%d Hz/%d channels/%d bit)\n", | |
139 ao_data.samplerate, ao_data.channels, bits_per_sample); | |
140 | |
141 return 1; | |
142 } | |
143 | |
144 | |
145 static void uninit(int immed) | |
146 { | |
147 int errval = 0; | |
148 | |
149 JACK_Reset(driver); | |
150 | |
151 if((errval = JACK_Close(driver))) | |
152 mp_msg(MSGT_AO, MSGL_ERR, | |
153 "AO: [Jack] error closing device, error %d\n", errval); | |
154 } | |
155 | |
156 | |
157 static int play(void* data,int len,int flags) | |
158 { | |
159 return JACK_Write(driver, data, len); | |
160 } | |
161 | |
162 | |
163 static void audio_pause() | |
164 { | |
165 JACK_SetState(driver, PAUSED); | |
166 } | |
167 | |
168 | |
169 static void audio_resume() | |
170 { | |
171 JACK_SetState(driver, PLAYING); | |
172 } | |
173 | |
174 | |
175 static void reset() | |
176 { | |
177 JACK_Reset(driver); | |
178 } | |
179 | |
180 | |
181 static int get_space() | |
182 { | |
183 return JACK_GetBytesFreeSpace(driver); | |
184 } | |
185 | |
186 | |
187 static float get_delay() | |
188 { | |
189 return (float )JACK_GetJackLatency(driver); | |
190 } | |
191 |