Switch to unified view

a/sc2src/alsadirect.cpp b/sc2src/alsadirect.cpp
...
...
46
#ifndef MIN
46
#ifndef MIN
47
#define MIN(A, B) ((A) < (B) ? (A) : (B))
47
#define MIN(A, B) ((A) < (B) ? (A) : (B))
48
#endif
48
#endif
49
49
50
// The queue for audio blocks ready for alsa. This is the maximum size
50
// The queue for audio blocks ready for alsa. This is the maximum size
51
// before enqueuing blocks
51
// before the upstream task blocks
52
static const unsigned int qs_hi = 100;
52
static const unsigned int qs_hi = 100;
53
53
54
// Queue size target including alsa buffers. There is no particular
54
// Queue size target including alsa buffers. There is no particular
55
// reason for the qs_hi/2 value. We could try something lower to
55
// reason for the qs_hi/2 value. We could try something lower to
56
// minimize latency
56
// minimize latency
...
...
128
                LOGERR("alsawriter: waitminsz failed\n");
128
                LOGERR("alsawriter: waitminsz failed\n");
129
                alsaqueue.workerExit();
129
                alsaqueue.workerExit();
130
                return (void *)1;
130
                return (void *)1;
131
            }
131
            }
132
        }
132
        }
133
133
        AudioMessage *tsk = 0;
134
        AudioMessage *tsk = 0;
134
        size_t qsz;
135
        if (!alsaqueue.take(&tsk, &qsz)) {
135
        if (!alsaqueue.take(&tsk)) {
136
            // TBD: reset alsa?
136
            // TBD: reset alsa?
137
            alsaqueue.workerExit();
137
            alsaqueue.workerExit();
138
            return (void*)1;
138
            return (void*)1;
139
        }
139
        }
140
140
...
...
142
        char *buf = tsk->m_buf;
142
        char *buf = tsk->m_buf;
143
        // This loop is copied from the alsa sample, but it should not
143
        // This loop is copied from the alsa sample, but it should not
144
        // be necessary, in synchronous mode, alsa is supposed to
144
        // be necessary, in synchronous mode, alsa is supposed to
145
        // perform complete writes except for errors or interrupts
145
        // perform complete writes except for errors or interrupts
146
        while (frames > 0) {
146
        while (frames > 0) {
147
//            LOGDEB("alsawriter: avail frames " << snd_pcm_avail(pcm) <<
148
//                   " writing " << frames << endl);
147
            snd_pcm_sframes_t ret =  snd_pcm_writei(pcm, tsk->m_buf, frames);
149
            snd_pcm_sframes_t ret =  snd_pcm_writei(pcm, tsk->m_buf, frames);
148
            if (ret != int(frames)) {
150
            if (ret != int(frames)) {
149
                LOGERR("snd_pcm_writei(" << frames <<" frames) failed: ret: " <<
151
                LOGERR("snd_pcm_writei(" << frames <<" frames) failed: ret: " <<
150
                       ret << endl);
152
                       ret << endl);
151
            } else {
153
            } else {
...
...
163
                    return (void*)1;
165
                    return (void*)1;
164
                }
166
                }
165
                qinit = false;
167
                qinit = false;
166
                break;
168
                break;
167
            }
169
            }
170
168
            unsigned int bytes = tsk->frames_to_bytes(ret);
171
            buf += tsk->frames_to_bytes(ret);
169
            buf += bytes;
170
            frames -= ret;
172
            frames -= ret;
171
        } 
173
        } 
172
174
173
        delete tsk;
175
        delete tsk;
174
    }
176
    }
175
}
177
}
176
178
177
static bool alsa_init(const string& dev, AudioMessage *tsk)
179
static bool alsa_init(const string& dev, AudioMessage *tsk)
178
{
180
{
179
    snd_pcm_hw_params_t *hwparams;
180
    int err;
181
    int err;
181
    const char *cmd = "";
182
    const char *cmd = "";
182
    unsigned int actual_rate = tsk->m_freq;
183
183
184
    if ((err = snd_pcm_open(&pcm, dev.c_str(), 
184
    if ((err = snd_pcm_open(&pcm, dev.c_str(), 
185
                            SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
185
                            SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
186
        LOGERR("alsa_init: snd_pcm_open " << dev << " " << 
186
        LOGERR("alsa_init: snd_pcm_open " << dev << " " << 
187
               snd_strerror(err) << endl);
187
               snd_strerror(err) << endl);
188
        return false;;
188
        return false;;
189
    }
189
    }
190
191
    snd_pcm_hw_params_t *hwparams;
190
    if ((err = snd_pcm_hw_params_malloc(&hwparams)) < 0) {
192
    snd_pcm_hw_params_alloca(&hwparams);
191
        LOGERR("alsa_init: snd_pcm_hw_params_malloc " << 
192
               snd_strerror(err) << endl);
193
        snd_pcm_close(pcm);
194
        return false;
195
    }
196
193
197
    cmd = "snd_pcm_hw_params_any";
194
    cmd = "snd_pcm_hw_params_any";
198
    if ((err = snd_pcm_hw_params_any(pcm, hwparams)) < 0) {
195
    if ((err = snd_pcm_hw_params_any(pcm, hwparams)) < 0) {
199
        goto error;
196
        goto error;
200
    }
197
    }
...
...
214
    if ((err = snd_pcm_hw_params_set_channels(pcm, hwparams,
211
    if ((err = snd_pcm_hw_params_set_channels(pcm, hwparams,
215
                                              tsk->m_chans)) < 0) {
212
                                              tsk->m_chans)) < 0) {
216
        goto error;
213
        goto error;
217
    }
214
    }
218
    cmd = "snd_pcm_hw_params_set_rate_near";
215
    cmd = "snd_pcm_hw_params_set_rate_near";
216
    unsigned int actual_rate;
217
    actual_rate = tsk->m_freq;
219
    if ((err = snd_pcm_hw_params_set_rate_near(pcm, hwparams, 
218
    if ((err = snd_pcm_hw_params_set_rate_near(pcm, hwparams, 
220
                                               &actual_rate, 0)) < 0) {
219
                                               &actual_rate, 0)) < 0) {
221
        goto error;
220
        goto error;
222
    }
221
    }
223
    if (actual_rate != tsk->m_freq) {
222
    if (actual_rate != tsk->m_freq) {
224
        LOGERR("snd_pcm_hw_params_set_rate_near: got actual rate "
223
        LOGERR("snd_pcm_hw_params_set_rate_near: got actual rate "
225
               << actual_rate << endl);
224
               << actual_rate << endl);
226
        goto error;
225
        goto error;
227
    }
226
    }
227
228
    // Note: we don't use these values, get them just for information purposes
228
    unsigned int periodsmin, periodsmax;
229
    unsigned int periodsmin, periodsmax;
229
    snd_pcm_hw_params_get_periods_min(hwparams, &periodsmin, 0);
230
    snd_pcm_hw_params_get_periods_min(hwparams, &periodsmin, 0);
230
    snd_pcm_hw_params_get_periods_max(hwparams, &periodsmax, 0);
231
    snd_pcm_hw_params_get_periods_max(hwparams, &periodsmax, 0);
231
    snd_pcm_uframes_t bsmax, bsmin, prmin, prmax;
232
    snd_pcm_uframes_t bsmax, bsmin, prmin, prmax;
232
    snd_pcm_hw_params_get_buffer_size_min(hwparams, &bsmin);
233
    snd_pcm_hw_params_get_buffer_size_min(hwparams, &bsmin);
...
...
239
240
240
    cmd = "snd_pcm_hw_params_set_buffer_time_near";
241
    cmd = "snd_pcm_hw_params_set_buffer_time_near";
241
    unsigned int buftimereq;
242
    unsigned int buftimereq;
242
    buftimereq = buffer_time;
243
    buftimereq = buffer_time;
243
    if ((err = snd_pcm_hw_params_set_buffer_time_near(pcm, hwparams,
244
    if ((err = snd_pcm_hw_params_set_buffer_time_near(pcm, hwparams,
244
                                                      &buffer_time, 0)) 
245
                                                      &buffer_time, 0)) < 0) {
245
        < 0) {
246
        goto error;
246
        goto error;
247
    }
247
    }
248
    LOGDEB("Alsa: set buffer_time_near: asked " <<buftimereq << " got " <<
248
    LOGDEB("Alsa: set buffer_time_near: asked " << buftimereq << " got " <<
249
           buffer_time << endl);
249
           buffer_time << endl);
250
250
251
    cmd = "snd_pcm_hw_params_set_period_time_near";
251
    cmd = "snd_pcm_hw_params_set_period_time_near";
252
    buftimereq = period_time;
252
    buftimereq = period_time;
253
    if ((err = snd_pcm_hw_params_set_period_time_near(pcm, hwparams,
253
    if ((err = snd_pcm_hw_params_set_period_time_near(pcm, hwparams,
254
                                                      &period_time, 0)) 
254
                                                      &period_time, 0)) < 0) {
255
        < 0) {
256
        goto error;
255
        goto error;
257
    }
256
    }
258
    LOGDEB("Alsa: set_period_time_near: asked " << buftimereq << " got " <<
257
    LOGDEB("Alsa: set_period_time_near: asked " << buftimereq << " got " <<
259
           period_time << endl);
258
           period_time << endl);
260
259
...
...
266
    cmd = "snd_pcm_hw_params";
265
    cmd = "snd_pcm_hw_params";
267
    if ((err = snd_pcm_hw_params(pcm, hwparams)) < 0) {
266
    if ((err = snd_pcm_hw_params(pcm, hwparams)) < 0) {
268
        goto error;
267
        goto error;
269
    }
268
    }
270
        
269
        
271
    snd_pcm_hw_params_free(hwparams);
272
273
    /* configure SW params */
270
    /* configure SW params */
274
    snd_pcm_sw_params_t *swparams;
271
    snd_pcm_sw_params_t *swparams;
275
    snd_pcm_sw_params_alloca(&swparams);
272
    snd_pcm_sw_params_alloca(&swparams);
276
273
277
    cmd = "snd_pcm_sw_params_current";
274
    cmd = "snd_pcm_sw_params_current";
...
...
297
294
298
    return true;
295
    return true;
299
296
300
error:
297
error:
301
    LOGERR("alsa_init: " << cmd << " error:" << snd_strerror(err) << endl);
298
    LOGERR("alsa_init: " << cmd << " error:" << snd_strerror(err) << endl);
302
    snd_pcm_hw_params_free(hwparams);
303
    return false;
299
    return false;
304
}
300
}
305
301
306
// Current in-driver delay in samples
302
// Current in-driver delay in samples
307
static int alsadelay()
303
static int alsadelay()