1 #include <errno.h>
2 #include <unistd.h>
3 #include "device_al.h"
4 #include "debug.h"
5 
6 
7 namespace audiere {
8 
9   ALAudioDevice*
create(const ParameterList & parameters)10   ALAudioDevice::create(const ParameterList& parameters) {
11     ADR_GUARD("ALAudioDevice::create");
12 
13     // if anything goes wrong, assume 44100 Hz
14     int rate = 44100;
15 
16     ADR_LOG("Getting resource");
17 
18     int device = alGetResourceByName(AL_SYSTEM, "DefaultOut", AL_DEVICE_TYPE);
19     if (device) {
20       ADR_LOG("Getting sampling rate");
21 
22       ALpv pv;
23       pv.param = AL_RATE;
24       if (-1 == alGetParams(device, &pv, 1)) {
25         fprintf(stderr, "Couldn't get rate: %s\n",
26                 alGetErrorString(oserror()));
27       }
28       rate = pv.value.i;
29     } else {
30       fprintf(stderr, "Couldn't get DefaultOut resource: %s\n",
31               alGetErrorString(oserror()));
32     }
33 
34     ADR_LOG("Creating config");
35 
36     ALconfig config = alNewConfig();
37     if (!config) {
38       fprintf(stderr, "Couldn't create ALconfig: %s\n",
39               alGetErrorString(oserror()));
40       return 0;
41     }
42 
43     ADR_LOG("Setting channels");
44 
45     // stereo
46     int result = alSetChannels(config, 2);
47     if (result != 0) {
48       fprintf(stderr, "Couldn't set channels: %s\n",
49               alGetErrorString(oserror()));
50       alFreeConfig(config);
51       return 0;
52     }
53 
54     ADR_LOG("Opening port");
55 
56     ALport port = alOpenPort("Audiere Output Port", "w", config);
57     if (!port) {
58       fprintf(stderr, "Couldn't open port: %s\n",
59               alGetErrorString(oserror()));
60       alFreeConfig(config);
61       return 0;
62     }
63 
64     ADR_LOG("Creating audio device");
65 
66     alFreeConfig(config);
67     return new ALAudioDevice(port, rate);
68   }
69 
70 
ALAudioDevice(ALport port,int rate)71   ALAudioDevice::ALAudioDevice(ALport port, int rate)
72     : MixerDevice(rate)
73   {
74     ADR_GUARD("ALAudioDevice::ALAudioDevice");
75 
76     m_port = port;
77   }
78 
79 
~ALAudioDevice()80   ALAudioDevice::~ALAudioDevice() {
81     ADR_GUARD("ALAudioDevice::~ALAudioDevice");
82 
83     alClosePort(m_port);
84   }
85 
86 
87   void
update()88   ALAudioDevice::update() {
89     ADR_GUARD("ALAudioDevice::update");
90 
91     // how much data can we write?
92     const int filled = alGetFilled(m_port);
93     int can_write = 5000 - filled;  // empty portion of the buffer
94 
95     // write 1024 frames at a time
96     static const int BUFFER_SIZE = 1024;
97     u8 buffer[BUFFER_SIZE * 4];
98     while (can_write > 0) {
99       int transfer_count = std::min(can_write, BUFFER_SIZE);
100 
101       ADR_LOG("reading");
102 
103       read(transfer_count, buffer);
104 
105       ADR_LOG("writing");
106 
107       alWriteFrames(m_port, buffer, transfer_count);
108       can_write -= transfer_count;
109     }
110 
111     usleep(50000);  // 50 milliseconds
112   }
113 
114 
115   const char* ADR_CALL
getName()116   ALAudioDevice::getName() {
117     return "sgial";
118   }
119 
120 }
121