1 #ifndef INCLUDED_AUDIO_IO_ALSA_PCM_H
2 #define INCLUDED_AUDIO_IO_ALSA_PCM_H
3 
4 #include <string>
5 #include <iostream>
6 
7 #include <sys/time.h>
8 #include <sys/types.h>
9 #include <sys/ioctl.h>
10 #include <unistd.h>
11 #include <fcntl.h>
12 
13 #include "sample-specs.h"
14 #include "samplebuffer.h"
15 #include "audioio-device.h"
16 
17 #include <alsa/asoundlib.h>
18 
19 using namespace std;
20 
21 /**
22  * Class for handling ALSA pcm-devices (Advanced Linux Sound Architecture).
23  */
24 class AUDIO_IO_ALSA_PCM : public AUDIO_IO_DEVICE {
25 
26  public:
27 
28   AUDIO_IO_ALSA_PCM (int card = 0, int device = 0, int subdevice = -1);
29   virtual ~AUDIO_IO_ALSA_PCM(void);
30   AUDIO_IO_ALSA_PCM* clone(void) const;
new_expr(void)31   AUDIO_IO_ALSA_PCM* new_expr(void) const { return new AUDIO_IO_ALSA_PCM(); }
32 
name(void)33   virtual string name(void) const { return("ALSA PCM device"); }
description(void)34   virtual string description(void) const { return("ALSA PCM devices. Alsa-lib versions 0.9.0 and newer."); }
35 
36   virtual void set_parameter(int param, string value);
37   virtual string get_parameter(int param) const;
38 
39   /** @name Function reimplemented from AUDIO_IO */
40   /*@{*/
41 
supported_io_modes(void)42   virtual int supported_io_modes(void) const { return(io_read | io_write); }
parameter_names(void)43   virtual string parameter_names(void) const { return("label,card,device,subdevice"); }
44 
45   virtual void open(void) throw(AUDIO_IO::SETUP_ERROR&);
46   virtual void close(void);
47 
48   virtual long int read_samples(void* target_buffer, long int samples);
49   virtual void write_samples(void* target_buffer, long int samples);
50 
51   /*@}*/
52 
53   /** @name Function reimplemented from AUDIO_IO_DEVICE */
54   /*@{*/
55 
56   virtual void prepare(void);
57   virtual void start(void);
58   virtual void stop(bool drain = false);
59 
60   virtual long int delay(void) const;
latency(void)61   virtual long int latency(void) const { return(buffersize()); }
prefill_space(void)62   virtual long int prefill_space(void) const { if (io_mode() != io_read) return(buffer_size_rep); else return(0); }
63 
64   /*@}*/
65 
66 private:
67 
68   void open_device(void);
69 
70   void allocate_structs(void);
71   void deallocate_structs(void);
72 
73   void set_audio_format_params(void);
74   void fill_and_set_hw_params(void);
75   void fill_and_set_sw_params(void);
76   void print_pcm_info(void);
77   void handle_xrun_print_gap_duration(snd_pcm_status_t *status);
78   void handle_xrun_capture(void);
79   void handle_xrun_playback(void);
80 
81 private:
82 
83   snd_pcm_t *audio_fd_repp;
84   snd_pcm_stream_t pcm_stream_rep;
85   snd_pcm_format_t format_rep;
86   snd_pcm_hw_params_t* pcm_hw_params_repp;
87   snd_pcm_sw_params_t* pcm_sw_params_repp;
88 
89   snd_pcm_uframes_t period_size_rep; /**< current period size return by alsa-lib */
90   snd_pcm_uframes_t buffer_size_rep; /**< current buffer size return by alsa-lib */
91 
92   int card_number_rep, device_number_rep, subdevice_number_rep;
93 
94   long underruns_rep, overruns_rep;
95   unsigned char **nbufs_repp;
96 
97   string pcm_device_name_rep;
98   static const string default_pcm_device_rep;
99 
100   bool using_plugin_rep;
101   bool trigger_request_rep;
102 
103  protected:
104 
105   void set_pcm_device_name(const string& n);
pcm_device_name(void)106   const string& pcm_device_name(void) const { return(pcm_device_name_rep); }
107 
108  private:
109 
AUDIO_IO_ALSA_PCM(const AUDIO_IO_ALSA_PCM & x)110   AUDIO_IO_ALSA_PCM (const AUDIO_IO_ALSA_PCM& x) { }
111   AUDIO_IO_ALSA_PCM& operator=(const AUDIO_IO_ALSA_PCM& x) { return *this; }
112 };
113 
114 #ifdef ECA_ENABLE_AUDIOIO_PLUGINS
115 extern "C" {
116 AUDIO_IO* audio_io_descriptor(void);
117 int audio_io_interface_version(void);
118 const char* audio_io_keyword(void);
119 const char* audio_io_keyword_regex(void);
120 };
121 #endif
122 
123 #endif /* INCLUDED_AUDIO_IO_ALSA_PCM_H */
124