static int op_jack_open(sample_format_t sf, const channel_position_t *cm) { sample_format = sf; if (fail) { /* jack went away so lets see if we can recover */ if (client != NULL) { op_jack_exit(); } if (op_jack_init() != OP_ERROR_SUCCESS) { return -OP_ERROR_INTERNAL; } } if (cm == NULL) { d_print("no channel_map\n"); return -OP_ERROR_NOT_SUPPORTED; } channel_map = cm; #ifdef HAVE_SAMPLERATE op_jack_reset_src(); resample_ratio = (float) jack_sample_rate / (float) sf_get_rate(sf); #else if (jack_sample_rate != sf_get_rate(sf)) { d_print("jack sample rate of %d does not match %d\n", jack_get_sample_rate(client), sf_get_rate(sf)); return -OP_ERROR_SAMPLE_FORMAT; } #endif if (sf_get_channels(sf) < CHANNELS) { d_print("%d channels not supported\n", sf_get_channels(sf)); return -OP_ERROR_SAMPLE_FORMAT; } int bits = sf_get_bits(sf); if (bits == 16) { sample_bytes = 2; read_sample = sf_get_signed(sf) ? &read_sample_le16 : &read_sample_le16u; } else if (bits == 24) { sample_bytes = 3; read_sample = sf_get_signed(sf) ? &read_sample_le24 : &read_sample_le24u; } else if (bits == 32) { sample_bytes = 4; read_sample = sf_get_signed(sf) ? &read_sample_le32 : &read_sample_le32u; } else { d_print("%d bits not supported\n", sf_get_bits(sf)); return -OP_ERROR_SAMPLE_FORMAT; } paused = false; return OP_ERROR_SUCCESS; }
static int sndio_set_sf(sample_format_t sf) { struct sio_par apar; sndio_sf = sf; sio_initpar(&par); par.pchan = sf_get_channels(sndio_sf); par.rate = sf_get_rate(sndio_sf); sndio_paused = 0; if (sf_get_signed(sndio_sf)) par.sig = 1; else par.sig = 0; if (sf_get_bigendian(sndio_sf)) par.le = 0; else par.le = 1; switch (sf_get_bits(sndio_sf)) { case 16: par.bits = 16; break; case 8: par.bits = 8; break; default: return -OP_ERROR_SAMPLE_FORMAT; } par.appbufsz = par.rate * 300 / 1000; apar = par; if (!sio_setpar(hdl, &par)) return -OP_ERROR_INTERNAL; if (!sio_getpar(hdl, &par)) return -OP_ERROR_INTERNAL; if (apar.rate != par.rate || apar.pchan != par.pchan || apar.bits != par.bits || (par.bits > 8 && apar.le != par.le) || apar.sig != par.sig) return -OP_ERROR_INTERNAL; sndio_mixer_set_volume(sndio_volume, sndio_volume); if (!sio_start(hdl)) return -OP_ERROR_INTERNAL; return OP_ERROR_SUCCESS; }
static int op_jack_sample_rate_cb(jack_nframes_t samples, void *arg) { #ifdef HAVE_SAMPLERATE resample_ratio = (float) sf_get_rate(sample_format) / (float) samples; #else if (jack_sample_rate != samples) { /* this cannot be handled */ fail = 1; return 1; } #endif return 0; }
static int waveout_open(sample_format_t sf) { WAVEFORMATEX format; int rc, i; /* WAVEFORMATEX does not support channels > 2, waveOutWrite() wants little endian signed PCM */ if (sf_get_bigendian(sf) || !sf_get_signed(sf) || sf_get_channels(sf) > 2) { return -OP_ERROR_SAMPLE_FORMAT; } memset(&format, 0, sizeof(format)); format.cbSize = sizeof(format); format.wFormatTag = WAVE_FORMAT_PCM; format.nChannels = sf_get_channels(sf); format.nSamplesPerSec = sf_get_rate(sf); format.wBitsPerSample = sf_get_bits(sf); format.nAvgBytesPerSec = sf_get_second_size(sf); format.nBlockAlign = sf_get_frame_size(sf); if ((rc = waveOutOpen(&wave_out, WAVE_MAPPER, &format, 0, 0, CALLBACK_NULL)) != MMSYSERR_NOERROR) { switch (rc) { case MMSYSERR_ALLOCATED: errno = EBUSY; return -OP_ERROR_ERRNO; case MMSYSERR_BADDEVICEID: case MMSYSERR_NODRIVER: errno = ENODEV; return -OP_ERROR_ERRNO; case MMSYSERR_NOMEM: errno = ENOMEM; return -OP_ERROR_ERRNO; case WAVERR_BADFORMAT: return -OP_ERROR_SAMPLE_FORMAT; } return -OP_ERROR_INTERNAL; } /* reset buffers */ for (i = 0; i < buffer_count; i++) { buffers[i].dwFlags = 0; } buffer_idx = 0; buffers_free = buffer_count; waveout_sf = sf; return 0; }
static int op_arts_open(sample_format_t sf, const channel_position_t *channel_map) { int buffer_time, server_latency, total_latency; int blocking; arts_sf = sf; arts_stream = arts_play_stream(sf_get_rate(arts_sf), sf_get_bits(arts_sf), sf_get_channels(arts_sf), "cmus"); blocking = arts_stream_set(arts_stream, ARTS_P_BLOCKING, 0); if (blocking) { } arts_buffer_size = arts_stream_get(arts_stream, ARTS_P_BUFFER_SIZE); if (arts_buffer_size < 0) { } buffer_time = arts_stream_get(arts_stream, ARTS_P_BUFFER_TIME); server_latency = arts_stream_get(arts_stream, ARTS_P_SERVER_LATENCY); total_latency = arts_stream_get(arts_stream, ARTS_P_TOTAL_LATENCY); d_print("buffer_time: %d\n", buffer_time); d_print("server_latency: %d\n", server_latency); d_print("total_latency: %d\n", total_latency); return 0; }
static int op_roar_open(sample_format_t sf, const channel_position_t *channel_map) { struct roar_audio_info info; int ret; memset(&info, 0, sizeof(info)); ROAR_DBG("op_roar_open(*) = ?"); format = sf; info.rate = sf_get_rate(sf); info.channels = sf_get_channels(sf); info.bits = sf_get_bits(sf); if (sf_get_bigendian(sf)) { if (sf_get_signed(sf)) { info.codec = ROAR_CODEC_PCM_S_BE; } else { info.codec = ROAR_CODEC_PCM_U_BE; } } else { if (sf_get_signed(sf)) { info.codec = ROAR_CODEC_PCM_S_LE; } else { info.codec = ROAR_CODEC_PCM_U_LE; } } ROAR_DBG("op_roar_open(*) = ?"); if (roar_libroar_set_server(host) == -1) { ROAR_DBG("op_roar_open(*) = ?"); roar_err_to_errno(); return -OP_ERROR_ERRNO; } if ( roar_simple_connect2(&con, NULL, "C* Music Player (cmus)", ROAR_ENUM_FLAG_NONBLOCK, 0) == -1 ) { ROAR_DBG("op_roar_open(*) = ?"); roar_err_to_errno(); return -OP_ERROR_ERRNO; } vss = roar_vs_new_from_con(&con, &err); if (vss == NULL) { ROAR_DBG("op_roar_open(*) = ?"); roar_disconnect(&con); _err_to_errno(); return -OP_ERROR_ERRNO; } if (roar_vs_stream(vss, &info, ROAR_DIR_PLAY, &err) == -1) { ROAR_DBG("op_roar_open(*) = ?"); roar_disconnect(&con); _err_to_errno(); return -OP_ERROR_ERRNO; } ROAR_DBG("op_roar_open(*) = ?"); if (roar_vs_buffer(vss, 2048*8, &err) == -1) { roar_vs_close(vss, ROAR_VS_TRUE, NULL); roar_disconnect(&con); _err_to_errno(); return -OP_ERROR_ERRNO; } ROAR_DBG("op_roar_open(*) = ?"); ret = _set_role(); if (ret != 0) { roar_vs_close(vss, ROAR_VS_TRUE, NULL); roar_disconnect(&con); _err_to_errno(); return ret; } ROAR_DBG("op_roar_open(*) = ?"); if (roar_vs_blocking(vss, ROAR_VS_FALSE, &err) == -1) { /* FIXME: handle this error */ } ROAR_DBG("op_roar_open(*) = 0"); return 0; }
descriptions[i].mCoordinates[2] = 0; } OSStatus err = AudioObjectSetPropertyData(dev_id, &aopa, 0, NULL, layout_size, layout); if (err != noErr) d_print("Cannot set the channel layout successfully.\n"); free(layout); } static AudioStreamBasicDescription coreaudio_fill_format_description(sample_format_t sf) { AudioStreamBasicDescription desc = { .mSampleRate = (Float64)sf_get_rate(sf), .mFormatID = kAudioFormatLinearPCM, .mFormatFlags = kAudioFormatFlagIsPacked, .mBytesPerPacket = sf_get_frame_size(sf), .mFramesPerPacket = 1, .mChannelsPerFrame = sf_get_channels(sf), .mBitsPerChannel = sf_get_bits(sf), .mBytesPerFrame = sf_get_frame_size(sf), }; d_print("Bits:%d\n", sf_get_bits(sf)); if (sf_get_bigendian(sf)) desc.mFormatFlags |= kAudioFormatFlagIsBigEndian; if (sf_get_signed(sf)) desc.mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger;
static int oss_set_sf(sample_format_t sf) { int tmp, log2_fragment_size, nr_fragments, bytes_per_second; oss_reset(); oss_sf = sf; #ifdef SNDCTL_DSP_CHANNELS tmp = sf_get_channels(oss_sf); if (ioctl(oss_fd, SNDCTL_DSP_CHANNELS, &tmp) == -1) return -1; #else tmp = sf_get_channels(oss_sf) - 1; if (ioctl(oss_fd, SNDCTL_DSP_STEREO, &tmp) == -1) return -1; #endif if (sf_get_bits(oss_sf) == 16) { if (sf_get_signed(oss_sf)) { if (sf_get_bigendian(oss_sf)) { tmp = AFMT_S16_BE; } else { tmp = AFMT_S16_LE; } } else { if (sf_get_bigendian(oss_sf)) { tmp = AFMT_U16_BE; } else { tmp = AFMT_U16_LE; } } } else if (sf_get_bits(oss_sf) == 8) { if (sf_get_signed(oss_sf)) { tmp = AFMT_S8; } else { tmp = AFMT_U8; } } else if (sf_get_bits(oss_sf) == 32 && sf_get_signed(oss_sf)) { if (sf_get_bigendian(oss_sf)) { tmp = AFMT_S32_BE; } else { tmp = AFMT_S32_LE; } } else if (sf_get_bits(oss_sf) == 24 && sf_get_signed(oss_sf) && !sf_get_bigendian(oss_sf)) { tmp = AFMT_S24_PACKED; } else { d_print("unsupported sample format: %c%u_%s\n", sf_get_signed(oss_sf) ? 'S' : 'U', sf_get_bits(oss_sf), sf_get_bigendian(oss_sf) ? "BE" : "LE"); return -1; } if (ioctl(oss_fd, SNDCTL_DSP_SAMPLESIZE, &tmp) == -1) return -1; tmp = sf_get_rate(oss_sf); if (ioctl(oss_fd, SNDCTL_DSP_SPEED, &tmp) == -1) return -1; bytes_per_second = sf_get_second_size(oss_sf); log2_fragment_size = 0; while (1 << log2_fragment_size < bytes_per_second / 25) log2_fragment_size++; log2_fragment_size--; nr_fragments = 32; /* bits 0..15 = size of fragment, 16..31 = log2(number of fragments) */ tmp = (nr_fragments << 16) + log2_fragment_size; if (ioctl(oss_fd, SNDCTL_DSP_SETFRAGMENT, &tmp) == -1) return -1; return 0; }