1 /* $Id: hw_audio_alsa.c,v 5.5 2008/07/03 21:33:52 lirc Exp $ */
3 /****************************************************************************
4 ** hw_audio_alsa.c *********************************************************
5 ****************************************************************************
7 * routines for using a IR receiver connected to soundcard ADC.
8 * Uses ALSA sound interface which is going to become standard
9 * in the 2.6 series of kernels. It does the same as ir_audio,
10 * but is linux-specific and does not require any exotic libraries
11 * for doing such simple work like recording an audio stream.
12 * Besides, its a lot more optimal since it uses 8kHz 8-bit
13 * mono sampling rather than 44KHz stereo 16-bit (a lot less CPU usage).
15 * Copyright (C) 2003 Andrew Zabolotny <andyz@users.sourceforge.net>
17 * Distribute under GPL version 2 or later.
19 * A detailed (:-) description of hardware can be found in the doc directory
20 * in the file ir-audio.html. Usage manual is in audio-alsa.html.
32 #include <sys/types.h>
35 #define ALSA_PCM_NEW_HW_PARAMS_API
36 #define ALSA_PCM_NEW_SW_PARAMS_API
37 #include <alsa/asoundlib.h>
40 #include "ir_remote.h"
44 /* SHORT DRIVER DESCRIPTION:
46 * This driver implements an adaptive input analyzer that does not depend
47 * of the input signal level, but for the sake of noise separation it is
48 * desired the level of input signal to be relatively strong (without
49 * clipping although it does not hurt).
51 * This driver works as following: it creates a named pipe (called usually
52 * /dev/lirc) and opens it. The handle is handed then to the receive.c module
53 * which reads or writes data from it. The client HAS to use non-blocking
54 * I/O otherwise we don't get a chance to run ever (this could be fixed
55 * by creating a secondary thread and doing all audio stuff there).
56 * If one day this driver will support sending commands, we'll have to use
57 * asyncronous I/O (O_ASYNC and a signal handler) so that we get control
58 * right after client writes to the pipe.
60 * For usage documentation see audio-alsa.html.
63 /* The following structure contains current sound card setup */
71 snd_pcm_format_t format
;
72 /* The audio buffer size in microseconds */
74 /* The FIFO handle for reading and writing */
76 /* The asynchronous I/O signal handler object */
77 snd_async_handler_t
*sighandler
;
78 /* Value indicating number of channels for capture */
79 unsigned char num_channels
;
80 /* Value indicating which channel to look for signal 0=right 1=left */
81 unsigned char channel
;
85 /* Desired sampling frequency */
87 /* Desired PCM format */
89 /* Reserve buffer for 0.1 secs of sampled data.
90 * If we use a larger buffer, our routine is called too seldom,
91 * and record.c thinks there is a time gap between data (and drops
98 0 /*Use left channel by default */
101 /* Return the absolute difference between two unsigned 8-bit samples */
102 #define U8_ABSDIFF(s1,s2) (((s1) >= (s2)) ? ((s1) - (s2)) : ((s2) - (s1)))
104 /* Forward declarations */
105 int audio_alsa_deinit (void);
106 static void alsa_sig_io (snd_async_handler_t
*h
);
108 static int alsa_error (const char *errstr
, int errcode
)
112 logprintf (LOG_ERR
, "ALSA function snd_pcm_%s returned error: %s",
113 errstr
, snd_strerror (errcode
));
114 logperror (LOG_ERR
, errstr
);
120 static int alsa_set_hwparams ()
122 snd_pcm_hw_params_t
*hwp
;
123 snd_pcm_sw_params_t
*swp
;
125 unsigned period_time
;
126 snd_pcm_uframes_t buffer_size
, period_size
;
128 snd_pcm_hw_params_alloca (&hwp
);
129 snd_pcm_sw_params_alloca (&swp
);
131 // ALSA bug? If we request 44100 Hz, it rounds the value up to 48000...
134 if (alsa_error ("hw_params_any",
135 snd_pcm_hw_params_any (alsa_hw
.handle
, hwp
))
136 || alsa_error ("hw_params_set_format",
137 snd_pcm_hw_params_set_format (alsa_hw
.handle
, hwp
, alsa_hw
.format
))
138 || alsa_error ("hw_params_set_channels",
139 snd_pcm_hw_params_set_channels (alsa_hw
.handle
, hwp
, alsa_hw
.num_channels
))
140 || alsa_error ("hw_params_set_rate_near",
141 snd_pcm_hw_params_set_rate_near (alsa_hw
.handle
, hwp
, &alsa_hw
.rate
, &dir
))
142 || alsa_error ("hw_params_set_access",
143 snd_pcm_hw_params_set_access (alsa_hw
.handle
, hwp
, SND_PCM_ACCESS_RW_INTERLEAVED
))
144 || alsa_error ("hw_params_set_buffer_time_near",
145 snd_pcm_hw_params_set_buffer_time_near (alsa_hw
.handle
, hwp
, &alsa_hw
.buffer_time
, 0)))
148 /* How often to call our SIGIO handler (~40Hz) */
149 period_time
= alsa_hw
.buffer_time
/ 4;
150 if (alsa_error ("hw_params_set_period_time_near",
151 snd_pcm_hw_params_set_period_time_near (alsa_hw
.handle
, hwp
, &period_time
, &dir
))
152 || alsa_error ("hw_params_get_buffer_size",
153 snd_pcm_hw_params_get_buffer_size (hwp
, &buffer_size
))
154 || alsa_error ("hw_params_get_period_size",
155 snd_pcm_hw_params_get_period_size (hwp
, &period_size
, 0))
156 || alsa_error ("hw_params",
157 snd_pcm_hw_params (alsa_hw
.handle
, hwp
)))
160 snd_pcm_sw_params_current (alsa_hw
.handle
, swp
);
161 if (alsa_error ("sw_params_set_start_threshold",
162 snd_pcm_sw_params_set_start_threshold (alsa_hw
.handle
, swp
, period_size
))
163 || alsa_error ("sw_params_set_avail_min",
164 snd_pcm_sw_params_set_avail_min (alsa_hw
.handle
, swp
, period_size
))
165 || alsa_error ("sw_params",
166 snd_pcm_sw_params (alsa_hw
.handle
, swp
)))
172 int audio_alsa_init ()
180 /* Create a temporary filename for our FIFO,
181 * Use mkstemp() instead of mktemp() although we need a FIFO not a
182 * regular file. We do this since glibc barfs at mktemp() and this
183 * scares the users :-)
185 strcpy (tmp_name
, "/tmp/lircXXXXXX");
186 fd
= mkstemp (tmp_name
);
189 /* Start the race! */
191 if (mknod (tmp_name
, S_IFIFO
| S_IRUSR
| S_IWUSR
, 0))
193 logprintf (LOG_ERR
, "could not create FIFO %s", tmp_name
);
194 logperror (LOG_ERR
, "audio_alsa_init ()");
197 /* Phew, we won the race ... */
199 /* Open the pipe and hand it to LIRC ... */
200 hw
.fd
= open (tmp_name
, O_RDWR
);
203 logprintf (LOG_ERR
, "could not open pipe %s", tmp_name
);
204 logperror (LOG_ERR
, "audio_alsa_init ()");
205 error
: unlink (tmp_name
);
206 audio_alsa_deinit ();
210 /* Open the other end of the pipe and hand it to ALSA code.
211 * We're opening it in non-blocking mode to avoid lockups.
213 alsa_hw
.fd
= open (tmp_name
, O_RDWR
| O_NONBLOCK
);
214 /* Ok, we don't need the FIFO visible in the filesystem anymore ... */
217 /* Examine the device name, if it contains a sample rate */
218 strncpy (tmp_name
, hw
.device
, sizeof (tmp_name
));
219 pcm_rate
= strchr (tmp_name
, '@');
223 char* stereo_channel
;
225 /* Examine if we need to capture in stereo
226 * looking for an 'l' or 'r' character to indicate
227 * which channel to look at.*/
228 stereo_channel
= strchr(pcm_rate
,',');
233 /* Syntax in device string indicates we need
235 alsa_hw
.num_channels
=2;
236 /* As we are requesting stereo now, use the
237 more common signed 16bit samples*/
238 alsa_hw
.format
= SND_PCM_FORMAT_S16_LE
;
240 if(stereo_channel
[1]=='l')
244 else if(stereo_channel
[1]=='r')
250 logperror(LOG_WARNING
,
251 "dont understand which channel "
252 "to use - defaulting to left\n");
256 /* Remove the sample rate from device name (and
257 channel indicator if present) */
259 /* See if rate is meaningful */
260 rate
= atoi (pcm_rate
);
267 /* Open the audio card in non-blocking mode */
268 err
= snd_pcm_open (&alsa_hw
.handle
, tmp_name
, SND_PCM_STREAM_CAPTURE
,
272 logprintf (LOG_ERR
, "could not open audio device %s: %s",
273 hw
.device
, snd_strerror (err
));
274 logperror (LOG_ERR
, "audio_alsa_init ()");
278 /* Set up the I/O signal handler */
279 if (alsa_error ("async_add_handler",
280 snd_async_add_pcm_handler (&alsa_hw
.sighandler
,
285 /* Set sampling parameters */
286 if (alsa_set_hwparams (alsa_hw
.handle
))
289 LOGPRINTF (LOG_INFO
, "hw_audio_alsa: Using device '%s', sampling rate %dHz\n",
290 tmp_name
, alsa_hw
.rate
);
292 /* Start sampling data */
293 if (alsa_error ("start", snd_pcm_start (alsa_hw
.handle
)))
299 int audio_alsa_deinit (void)
301 if (alsa_hw
.sighandler
)
303 snd_async_del_handler (alsa_hw
.sighandler
);
304 alsa_hw
.sighandler
= NULL
;
308 snd_pcm_close (alsa_hw
.handle
);
309 alsa_hw
.handle
= NULL
;
311 if (alsa_hw
.fd
!= -1)
325 * ALSA calls this callback when some data is available for reading.
326 * The detection algorithm is somewhat sophisticated but it should give
327 * good practical results. The algorithm works as follows:
329 * Sampled data is converted to unsigned form (e.g. 0x80 is zero).
331 * The current "middle" value is constantly tracked (e.g. signal
332 * could deviate from the 0x80 by a certain amount due to soundcard
333 * entry capacitance). Then we subtract that middle from every sample
334 * to get a signed value (to know whether it is less or more than current
335 * tracked "zero" value). This is called 'current sample'.
337 * The absolute value of current sample is integrated over time to get
338 * automatic level correction (e.g. to smooth the difference between
339 * different hardware which can have different output levels). This is
340 * called 'signal level'.
342 * Then the algorithm waits for a substantial change in the level of
343 * input signals (since IR module outputs a square wave). When this
344 * substantial change crosses our "virtual zero", it is considered
345 * a real level change, and the type of signal is toggled
349 #define READ_BUFFER_SIZE (2*4096)
351 static void alsa_sig_io (snd_async_handler_t
*h
)
353 /* Previous sample */
354 static unsigned char ps
= 0x80;
355 /* Count samples with similar level (to detect pule/space
357 static unsigned sample_count
= 0;
358 /* Current signal level (dynamically changes) */
359 static unsigned signal_level
= 0;
360 /* Current state (pulse or space) */
361 static unsigned signal_state
= 0;
362 /* Signal maximum and minimum (used for "zero" detection) */
363 static unsigned char signal_max
= 0x80, signal_min
= 0x80;
364 /* Non-zero if we're in zero crossing waiting state */
365 static char waiting_zerox
= 0;
366 /* Store sample size, as our sample buffer will represent
368 unsigned char bytes_per_sample
=
369 (alsa_hw
.format
== SND_PCM_FORMAT_S16_LE
? 2 : 1);
372 char buff
[READ_BUFFER_SIZE
];
373 snd_pcm_sframes_t count
;
375 /* The value to multiply with number of samples to get microseconds
376 * (fixed-point 24.8 bits).
378 unsigned mulconst
= 256000000 / alsa_hw
.rate
;
379 /* Maximal number of samples that can be multiplied by mulconst */
380 unsigned maxcount
= (((PULSE_MASK
<< 8) | 0xff) / mulconst
) << 8;
382 /* First of all, check for underrun. This happens, for example, when
383 * the X11 server starts. If we won't, recording will stop forever.
385 snd_pcm_state_t state
= snd_pcm_state (alsa_hw
.handle
);
388 case SND_PCM_STATE_SUSPENDED
:
389 while ((err
= snd_pcm_resume (alsa_hw
.handle
)) == -EAGAIN
)
390 /* wait until the suspend flag is released */
395 case SND_PCM_STATE_XRUN
:
396 alsa_error ("prepare", snd_pcm_prepare (alsa_hw
.handle
));
397 alsa_error ("start", snd_pcm_start (alsa_hw
.handle
));
398 var_reset
: /* Reset variables */
403 signal_max
= signal_min
= 0x80;
410 /* Read all available data */
411 if ((count
= snd_pcm_avail_update (alsa_hw
.handle
)) > 0)
413 if (count
> (READ_BUFFER_SIZE
/ (bytes_per_sample
*alsa_hw
.num_channels
)))
414 count
= READ_BUFFER_SIZE
/ (bytes_per_sample
*alsa_hw
.num_channels
);
415 count
= snd_pcm_readi(alsa_hw
.handle
, buff
, count
);
417 /*Loop around samples, if stereo we are
418 *only interested in one channel*/
419 for (i
= 0; i
< count
; i
++)
421 /* cs == current sample */
422 unsigned char cs
, as
, sl
, sz
, xz
;
424 if(bytes_per_sample
== 2){
425 cs
= ((*(short*)&buff
[i
*bytes_per_sample
*alsa_hw
.num_channels
+
426 bytes_per_sample
*alsa_hw
.channel
]) >> 8);
432 /* Convert signed samples to unsigned */
433 if(alsa_hw
.format
== SND_PCM_FORMAT_S8
)
439 /* Track signal middle value (it could differ from 0x80) */
440 sz
= (signal_min
+ signal_max
) / 2;
442 signal_min
= (signal_min
* 7 + cs
) / 8;
444 signal_max
= (signal_max
* 7 + cs
) / 8;
446 /* Compute the absolute signal deviation from middle */
447 as
= U8_ABSDIFF (cs
, sz
);
449 /* Integrate incoming signal (auto level adjustment) */
450 signal_level
= (signal_level
* 7 + as
) / 8;
452 /* Don't let too low signal levels as it makes us sensible to noise */
454 if (sl
< 16) sl
= 16;
456 /* Detect crossing current "zero" level */
457 xz
= ((cs
- sz
) ^ (ps
- sz
)) & 0x80;
459 /* Don't wait for zero crossing for too long */
460 if (waiting_zerox
&& !xz
)
463 /* Detect significant signal level changes */
464 if ((abs (cs
- ps
) > sl
/2) && xz
)
467 /* If we have crossed zero with a substantial level change, go */
468 if (waiting_zerox
&& xz
)
474 if (sample_count
>= maxcount
)
482 * Try to interpolate the samples and determine where exactly
483 * the zero crossing point was. This is required as the
484 * remote signal frequency is relatively close to our sampling
485 * frequency thus a sampling error of 1 sample can lead to
486 * substantial time differences.
488 * slope = (x2 - x1) / (y2 - y1)
489 * x = x1 + (y - y1) * slope
491 * where x1=-1, x2=0, y1=ps, y2=cs, y=sz, thus:
493 * x = -1 + (y - y1) / (y2 - y1), or
494 * ==> x = (y - y2) / (y2 - y1)
496 * y2 (cs) cannot be equal to y1 (ps), otherwise we wouldn't
499 int delta
= (((int)sz
- (int)cs
) << 8) / ((int)cs
- (int)ps
);
500 /* This expression can easily overflow the 'long' value since it
501 * multiplies two 24.8 values (and we get a 24.16 instead).
502 * To avoid this we cast the intermediate value to "long long".
504 x
= (((long long)sample_count
+ delta
) * mulconst
) >> 16;
505 /* The rest of the quantum is on behalf of next pulse. Note that
506 * sample_count can easily be assigned here a negative value (in
507 * the case zero crossing occurs during the next quantum).
509 sample_count
= -delta
;
512 /* Consider impossible pulses with length greater than
513 * 0.02 seconds, thus it is a space (desynchronization).
515 if ((x
> 20000) && signal_state
)
518 LOGPRINTF (1, "Pulse/space desynchronization fixed - len %u",x
);
523 /* Write the LIRC code to the FIFO */
524 write (alsa_hw
.fd
, &x
, sizeof (x
));
526 signal_state
^= PULSE_BIT
;
529 /* Remember previous sample */
532 /* Count number of samples with the same level.
533 * sample_count can be less than zero at the start of pulse
534 * (due to interpolation) so we have to consider them.
536 if ((sample_count
< UINT_MAX
- 0x400)
537 || (sample_count
> UINT_MAX
- 0x200))
538 sample_count
+= 0x100;
543 lirc_t
audio_alsa_readdata (lirc_t timeout
)
548 if (!waitfordata ((long) timeout
))
551 ret
= read (hw
.fd
, &data
, sizeof (data
));
553 if (ret
!= sizeof (data
))
555 LOGPRINTF (1, "error reading from lirc device");
563 char *audio_alsa_rec (struct ir_remote
*remotes
)
565 if (!clear_rec_buffer ())
567 return decode_all (remotes
);
570 #define audio_alsa_decode receive_decode
572 struct hardware hw_audio_alsa
=
574 "hw", /* default device */
576 LIRC_CAN_REC_MODE2
, /* features */
578 LIRC_MODE_MODE2
, /* rec_mode */
580 audio_alsa_init
, /* init_func */
581 NULL
, /* config_func */
582 audio_alsa_deinit
, /* deinit_func */
583 NULL
, /* send_func */
584 audio_alsa_rec
, /* rec_func */
585 audio_alsa_decode
, /* decode_func */
586 NULL
, /* ioctl_func */