void ossPrimitiveFileOp::Close() { if (isValid() && (!_bIsStdout)) { oss_close(_fileHandle); _fileHandle = OSS_INVALID_HANDLE_FD_VALUE; } }
static void oss_close_in(void) { oss_close(); if (dsp_mode == O_RDWR) { if (oss_open(O_WRONLY)) oss_restore_format(); } }
static void oss_close_out(void) { oss_close(); if (dsp_mode == O_RDWR) { if (oss_open(O_RDONLY)) oss_restore_format(); } /* Ack all remaining packets */ while (!rdpsnd_queue_empty()) rdpsnd_queue_next(0); }
static int oss_open(sample_format_t sf, const channel_position_t *channel_map) { int oss_version = 0; oss_fd = open(oss_dsp_device, O_WRONLY); if (oss_fd == -1) return -1; ioctl(oss_fd, OSS_GETVERSION, &oss_version); d_print("oss version: %#08x\n", oss_version); if (oss_set_sf(sf) == -1) { oss_close(); return -1; } return 0; }
/* "Public" function, called from a libspotify callback */ G_MODULE_EXPORT int audio_delivery(const sp_audioformat* format, const void* frames, int num_frames) { int ret; g_mutex_lock(&g_oss_mutex); /* What are we supposed to do here? */ if (num_frames == 0) { /* Pause: close the device */ if (g_oss_fd != -1) oss_close(); ret = 0; } else { if (g_oss_fd == -1) { /* Some frames to play, but the device is closed: open it and set it up */ oss_open(); oss_setup(format); } /* Is the device ready to be written to? */ ret = poll(&g_pfd, 1, 0); if (ret == -1) g_error("Can't poll OSS device: %s", g_strerror(errno)); else if (ret != 0) { /* Ok, we can write to the device without blocking */ ret = write(g_oss_fd, frames, g_oss_frame_size * num_frames); if (ret == -1) g_error("Can't write to OSS device: %s", g_strerror(errno)); ret /= g_oss_frame_size; } } g_mutex_unlock(&g_oss_mutex); return ret; }
static RD_BOOL oss_set_format(RD_WAVEFORMATEX * pwfx) { int fragments; static RD_BOOL driver_broken = False; assert(dsp_fd != -1); if (dsp_configured) { if ((pwfx->wBitsPerSample == 8) && (format != AFMT_U8)) return False; if ((pwfx->wBitsPerSample == 16) && (format != AFMT_S16_LE)) return False; if ((pwfx->nChannels == 2) != ! !stereo) return False; if (pwfx->nSamplesPerSec != snd_rate) return False; return True; } ioctl(dsp_fd, SNDCTL_DSP_RESET, NULL); ioctl(dsp_fd, SNDCTL_DSP_SYNC, NULL); if (pwfx->wBitsPerSample == 8) format = AFMT_U8; else if (pwfx->wBitsPerSample == 16) format = AFMT_S16_LE; samplewidth = pwfx->wBitsPerSample / 8; if (ioctl(dsp_fd, SNDCTL_DSP_SETFMT, &format) == -1) { perror("SNDCTL_DSP_SETFMT"); oss_close(); return False; } if (pwfx->nChannels == 2) { stereo = 1; samplewidth *= 2; } else { stereo = 0; } if (ioctl(dsp_fd, SNDCTL_DSP_STEREO, &stereo) == -1) { perror("SNDCTL_DSP_CHANNELS"); oss_close(); return False; } oss_driver.need_resampling = 0; snd_rate = pwfx->nSamplesPerSec; if (ioctl(dsp_fd, SNDCTL_DSP_SPEED, &snd_rate) == -1) { uint32 rates[] = { 44100, 48000, 0 }; uint32 *prates = rates; while (*prates != 0) { if ((pwfx->nSamplesPerSec != *prates) && (ioctl(dsp_fd, SNDCTL_DSP_SPEED, prates) != -1)) { oss_driver.need_resampling = 1; snd_rate = *prates; if (rdpsnd_dsp_resample_set (snd_rate, pwfx->wBitsPerSample, pwfx->nChannels) == False) { error("rdpsnd_dsp_resample_set failed"); oss_close(); return False; } break; } prates++; } if (*prates == 0) { perror("SNDCTL_DSP_SPEED"); oss_close(); return False; } } /* try to get 12 fragments of 2^12 bytes size */ fragments = (12 << 16) + 12; ioctl(dsp_fd, SNDCTL_DSP_SETFRAGMENT, &fragments); if (!driver_broken) { audio_buf_info info; memset(&info, 0, sizeof(info)); if (ioctl(dsp_fd, SNDCTL_DSP_GETOSPACE, &info) == -1) { perror("SNDCTL_DSP_GETOSPACE"); oss_close(); return False; } if (info.fragments == 0 || info.fragstotal == 0 || info.fragsize == 0) { fprintf(stderr, "Broken OSS-driver detected: fragments: %d, fragstotal: %d, fragsize: %d\n", info.fragments, info.fragstotal, info.fragsize); driver_broken = True; } } dsp_configured = True; return True; }