static BOOL tsmf_alsa_open(ITSMFAudioDevice *audio, const char *device) { TSMFAlsaAudioDevice *alsa = (TSMFAlsaAudioDevice *) audio; if(!device) { strncpy(alsa->device, "default", sizeof(alsa->device)); } else { strncpy(alsa->device, device, sizeof(alsa->device)); } return tsmf_alsa_open_device(alsa); }
static boolean tsmf_alsa_open(ITSMFAudioDevice* audio, const char* device) { TSMFALSAAudioDevice* alsa = (TSMFALSAAudioDevice*) audio; if (!device) { if (!alsa->device[0]) strcpy(alsa->device, "default"); } else { strcpy(alsa->device, device); } return tsmf_alsa_open_device(alsa); }
static BOOL tsmf_alsa_play(ITSMFAudioDevice *audio, BYTE *data, UINT32 data_size) { int len; int error; int frames; BYTE *end; BYTE *src; BYTE *pindex; int rbytes_per_frame; int sbytes_per_frame; TSMFAlsaAudioDevice *alsa = (TSMFAlsaAudioDevice *) audio; DEBUG_TSMF("data_size %d", data_size); if(alsa->out_handle) { sbytes_per_frame = alsa->source_channels * alsa->bytes_per_sample; rbytes_per_frame = alsa->actual_channels * alsa->bytes_per_sample; if((alsa->source_rate == alsa->actual_rate) && (alsa->source_channels == alsa->actual_channels)) { src = data; } else { alsa->dsp_context->resample(alsa->dsp_context, data, alsa->bytes_per_sample, alsa->source_channels, alsa->source_rate, data_size / sbytes_per_frame, alsa->actual_channels, alsa->actual_rate); frames = alsa->dsp_context->resampled_frames; DEBUG_TSMF("resampled %d frames at %d to %d frames at %d", data_size / sbytes_per_frame, alsa->source_rate, frames, alsa->actual_rate); data_size = frames * rbytes_per_frame; src = alsa->dsp_context->resampled_buffer; } pindex = src; end = pindex + data_size; while(pindex < end) { len = end - pindex; frames = len / rbytes_per_frame; error = snd_pcm_writei(alsa->out_handle, pindex, frames); if(error == -EPIPE) { snd_pcm_recover(alsa->out_handle, error, 0); error = 0; } else if(error < 0) { DEBUG_TSMF("error len %d", error); snd_pcm_close(alsa->out_handle); alsa->out_handle = 0; tsmf_alsa_open_device(alsa); break; } DEBUG_TSMF("%d frames played.", error); if(error == 0) break; pindex += error * rbytes_per_frame; } } free(data); return TRUE; }