2
Copyright (C) 2001 Paul Davis
4
This program is free software; you can redistribute it and/or modify
5
it under the terms of the GNU General Public License as published by
6
the Free Software Foundation; either version 2 of the License, or
7
(at your option) any later version.
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
GNU General Public License for more details.
14
You should have received a copy of the GNU General Public License
15
along with this program; if not, write to the Free Software
16
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
#include <jack/hardware.h>
21
#include "alsa_driver.h"
22
#include "hammerfall.h"
23
#include <jack/internal.h>
25
/* Set this to 1 if you want this compile error:
26
* warning: `hammerfall_monitor_controls' defined but not used */
27
#define HAMMERFALL_MONITOR_CONTROLS 0
30
set_control_id (snd_ctl_elem_id_t *ctl, const char *name)
32
snd_ctl_elem_id_set_name (ctl, name);
33
snd_ctl_elem_id_set_numid (ctl, 0);
34
snd_ctl_elem_id_set_interface (ctl, SND_CTL_ELEM_IFACE_MIXER);
35
snd_ctl_elem_id_set_device (ctl, 0);
36
snd_ctl_elem_id_set_subdevice (ctl, 0);
37
snd_ctl_elem_id_set_index (ctl, 0);
40
#if HAMMERFALL_MONITOR_CONTROLS
42
hammerfall_broadcast_channel_status_change (hammerfall_t *h, int lock, int sync, channel_t lowchn, channel_t highchn)
46
ClockSyncStatus status = 0;
60
for (chn = lowchn; chn < highchn; chn++) {
61
alsa_driver_set_clock_sync_status (h->driver, chn, status);
66
hammerfall_check_sync_state (hammerfall_t *h, int val, int adat_id)
72
/* S/PDIF channel is always locked and synced, but we only
73
need tell people once that this is TRUE.
75
XXX - maybe need to make sure that the rate matches our
76
idea of the current rate ?
79
if (!h->said_that_spdif_is_fine) {
80
ClockSyncStatus status;
84
/* XXX broken! fix for hammerfall light ! */
86
alsa_driver_set_clock_sync_status (h->driver, 24, status);
87
alsa_driver_set_clock_sync_status (h->driver, 25, status);
89
h->said_that_spdif_is_fine = TRUE;
92
lock = (val & 0x1) ? TRUE : FALSE;
93
sync = (val & 0x2) ? TRUE : FALSE;
95
if (h->lock_status[adat_id] != lock ||
96
h->sync_status[adat_id] != sync) {
97
hammerfall_broadcast_channel_status_change (h, lock, sync, adat_id*8, (adat_id*8)+8);
100
h->lock_status[adat_id] = lock;
101
h->sync_status[adat_id] = sync;
105
hammerfall_check_sync (hammerfall_t *h, snd_ctl_elem_value_t *ctl)
110
snd_ctl_elem_id_t *ctl_id;
112
jack_info ("check sync");
114
snd_ctl_elem_id_alloca (&ctl_id);
115
snd_ctl_elem_value_get_id (ctl, ctl_id);
117
name = snd_ctl_elem_id_get_name (ctl_id);
119
if (strcmp (name, "ADAT1 Sync Check") == 0) {
120
val = snd_ctl_elem_value_get_enumerated (ctl, 0);
121
hammerfall_check_sync_state (h, val, 0);
122
} else if (strcmp (name, "ADAT2 Sync Check") == 0) {
123
val = snd_ctl_elem_value_get_enumerated (ctl, 0);
124
hammerfall_check_sync_state (h, val, 1);
125
} else if (strcmp (name, "ADAT3 Sync Check") == 0) {
126
val = snd_ctl_elem_value_get_enumerated (ctl, 0);
127
hammerfall_check_sync_state (h, val, 2);
129
jack_error ("Hammerfall: unknown control \"%s\"", name);
132
#endif /* HAMMERFALL_MONITOR_CONTROLS */
135
hammerfall_set_input_monitor_mask (jack_hardware_t *hw, unsigned long mask)
137
hammerfall_t *h = (hammerfall_t *) hw->private;
138
snd_ctl_elem_value_t *ctl;
139
snd_ctl_elem_id_t *ctl_id;
143
snd_ctl_elem_value_alloca (&ctl);
144
snd_ctl_elem_id_alloca (&ctl_id);
145
set_control_id (ctl_id, "Channels Thru");
146
snd_ctl_elem_value_set_id (ctl, ctl_id);
148
for (i = 0; i < 26; i++) {
149
snd_ctl_elem_value_set_integer (ctl, i, (mask & (1<<i)) ? 1 : 0);
152
if ((err = snd_ctl_elem_write (h->driver->ctl_handle, ctl)) != 0) {
153
jack_error ("ALSA/Hammerfall: cannot set input monitoring (%s)", snd_strerror (err));
157
hw->input_monitor_mask = mask;
163
hammerfall_change_sample_clock (jack_hardware_t *hw, SampleClockMode mode)
165
hammerfall_t *h = (hammerfall_t *) hw->private;
166
snd_ctl_elem_value_t *ctl;
167
snd_ctl_elem_id_t *ctl_id;
170
snd_ctl_elem_value_alloca (&ctl);
171
snd_ctl_elem_id_alloca (&ctl_id);
172
set_control_id (ctl_id, "Sync Mode");
173
snd_ctl_elem_value_set_id (ctl, ctl_id);
177
snd_ctl_elem_value_set_enumerated (ctl, 0, 0);
180
snd_ctl_elem_value_set_enumerated (ctl, 0, 1);
183
snd_ctl_elem_value_set_enumerated (ctl, 0, 2);
187
if ((err = snd_ctl_elem_write (h->driver->ctl_handle, ctl)) < 0) {
188
jack_error ("ALSA-Hammerfall: cannot set clock mode");
195
hammerfall_release (jack_hardware_t *hw)
198
hammerfall_t *h = (hammerfall_t *) hw->private;
205
pthread_cancel (h->monitor_thread);
206
pthread_join (h->monitor_thread, &status);
211
#if HAMMERFALL_MONITOR_CONTROLS
213
hammerfall_monitor_controls (void *arg)
215
jack_hardware_t *hw = (jack_hardware_t *) arg;
216
hammerfall_t *h = (hammerfall_t *) hw->private;
217
snd_ctl_elem_id_t *switch_id[3];
218
snd_ctl_elem_value_t *sw[3];
220
pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
222
snd_ctl_elem_id_malloc (&switch_id[0]);
223
snd_ctl_elem_id_malloc (&switch_id[1]);
224
snd_ctl_elem_id_malloc (&switch_id[2]);
226
snd_ctl_elem_value_malloc (&sw[0]);
227
snd_ctl_elem_value_malloc (&sw[1]);
228
snd_ctl_elem_value_malloc (&sw[2]);
230
set_control_id (switch_id[0], "ADAT1 Sync Check");
231
set_control_id (switch_id[1], "ADAT2 Sync Check");
232
set_control_id (switch_id[2], "ADAT3 Sync Check");
234
snd_ctl_elem_value_set_id (sw[0], switch_id[0]);
235
snd_ctl_elem_value_set_id (sw[1], switch_id[1]);
236
snd_ctl_elem_value_set_id (sw[2], switch_id[2]);
239
if (snd_ctl_elem_read (h->driver->ctl_handle, sw[0])) {
240
jack_error ("cannot read control switch 0 ...");
242
hammerfall_check_sync (h, sw[0]);
244
if (snd_ctl_elem_read (h->driver->ctl_handle, sw[1])) {
245
jack_error ("cannot read control switch 0 ...");
247
hammerfall_check_sync (h, sw[1]);
249
if (snd_ctl_elem_read (h->driver->ctl_handle, sw[2])) {
250
jack_error ("cannot read control switch 0 ...");
252
hammerfall_check_sync (h, sw[2]);
254
if (nanosleep (&h->monitor_interval, 0)) {
261
#endif /* HAMMERFALL_MONITOR_CONTROLS */
264
jack_alsa_hammerfall_hw_new (alsa_driver_t *driver)
270
hw = (jack_hardware_t *) malloc (sizeof (jack_hardware_t));
272
hw->capabilities = Cap_HardwareMonitoring|Cap_AutoSync|Cap_WordClock|Cap_ClockMaster|Cap_ClockLockReporting;
273
hw->input_monitor_mask = 0;
276
hw->set_input_monitor_mask = hammerfall_set_input_monitor_mask;
277
hw->change_sample_clock = hammerfall_change_sample_clock;
278
hw->release = hammerfall_release;
280
h = (hammerfall_t *) malloc (sizeof (hammerfall_t));
282
h->lock_status[0] = FALSE;
283
h->sync_status[0] = FALSE;
284
h->lock_status[1] = FALSE;
285
h->sync_status[1] = FALSE;
286
h->lock_status[2] = FALSE;
287
h->sync_status[2] = FALSE;
288
h->said_that_spdif_is_fine = FALSE;
291
h->monitor_interval.tv_sec = 1;
292
h->monitor_interval.tv_nsec = 0;
297
if (pthread_create (&h->monitor_thread, 0, hammerfall_monitor_controls, hw)) {
298
jack_error ("ALSA/Hammerfall: cannot create sync monitor thread");