Beispiel #1
0
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;
}
Beispiel #2
0
/* init or resize buffers if needed */
static int op_jack_buffer_init(jack_nframes_t samples, void *arg)
{
	if (buffer_size > samples * BUFFER_MULTIPLYER) {
		/* we just don't shrink buffers, since this could result
		 * in gaps and they won't get that big anyway
		 */
		return 0;
	}

	buffer_size = samples * BUFFER_MULTIPLYER;
	if (buffer_size < BUFFER_SIZE_MIN) {
		buffer_size = BUFFER_SIZE_MIN;
	}
	d_print("new buffer size %zu\n", buffer_size);

	char *tmp = xmalloc(buffer_size);

	for (int i = 0; i < CHANNELS; i++) {
		jack_ringbuffer_t *new_buffer = jack_ringbuffer_create(buffer_size);

		if (!new_buffer) {
			d_print("ringbuffer alloc failed\n");
			free(tmp);
			fail = 1;
			op_jack_exit();
			return 1;
		}
		if (ringbuffer[i] != NULL) {
			size_t length = jack_ringbuffer_read_space(ringbuffer[i]);

			/* actualy this could both read/write less than length.
			 * In that case, which should not happen[TM], there will
			 * be a gap in playback.
			 */
			jack_ringbuffer_read(ringbuffer[i], tmp, length);
			jack_ringbuffer_write(new_buffer, tmp, length);

			jack_ringbuffer_free(ringbuffer[i]);
		}

		ringbuffer[i] = new_buffer;
	}

	free(tmp);
	return 0;
}
Beispiel #3
0
static int op_jack_buffer_space(void)
{
	if (fail) {
		op_jack_exit();
		return -OP_ERROR_INTERNAL;
	}

	int bytes = jack_ringbuffer_write_space(ringbuffer[0]);
	for (int c = 1; c < CHANNELS; c++) {
		int tmp = jack_ringbuffer_write_space(ringbuffer[0]);
		if (bytes > tmp) {
			bytes = tmp;
		}
	}

	int frames = bytes / sizeof(jack_default_audio_sample_t);
	int frame_size = sf_get_frame_size(sample_format);

#ifdef HAVE_SAMPLERATE
	return (int) ((float) (frames) / resample_ratio) * frame_size;
#else
	return frames * frame_size;
#endif
}
Beispiel #4
0
static int op_jack_write(const char *buffer, int count)
{
	if (fail) {
		op_jack_exit();
		return -OP_ERROR_INTERNAL;
	}

	if (!drop_done) {
		return 0;
	}

	int frame_size = sf_get_frame_size(sample_format);
	int channels = sf_get_channels(sample_format);
	size_t frames = count / frame_size;

	/* since this is the only place where the ringbuffers get
	 * written, available space will only grow, therefore frames_min
	 * is safe.
	 */
	size_t frames_min = SIZE_MAX;
	for (int c = 0; c < CHANNELS; c++) {
		size_t frames_available = jack_ringbuffer_write_space(ringbuffer[c]) / sizeof(jack_default_audio_sample_t);
		if (frames_available < frames_min) {
			frames_min = frames_available;
		}
	}

	if (frames > frames_min) {
		frames = frames_min;
	}

	jack_default_audio_sample_t buf[CHANNELS][buffer_size];

	/* demux and convert to float */
	for (int pos = 0; pos < count; ) {
		int frame = pos / frame_size;
		for (int c = 0; c < channels; c++) {
			int idx = pos + c * sample_bytes;
			/* for now, only 2 channels and mono are supported */
			if (channel_map[c] == CHANNEL_POSITION_LEFT || channel_map[c] == CHANNEL_POSITION_MONO) {
				buf[0][frame] = read_sample(&buffer[idx]);
			} else if (channel_map[c] == CHANNEL_POSITION_RIGHT || channel_map[c] == CHANNEL_POSITION_MONO) {
				buf[1][frame] = read_sample(&buffer[idx]);
			}
		}
		pos += frame_size;
	}

#ifdef HAVE_SAMPLERATE
	if (resample_ratio > 1.01f || resample_ratio < 0.99) {
		jack_default_audio_sample_t converted[buffer_size];
		SRC_DATA src_data;
		for (int c = 0; c < CHANNELS; c++) {
			src_data.data_in = buf[c];
			src_data.data_out = converted;
			src_data.input_frames = frames;
			src_data.output_frames = frames_min;
			src_data.src_ratio = resample_ratio;
			src_data.end_of_input = 0;

			int err = src_process(src_state[c], &src_data);
			if (err) {
				d_print("libsamplerate err %s\n", src_strerror(err));
			}

			int byte_length = src_data.output_frames_gen * sizeof(jack_default_audio_sample_t);
			jack_ringbuffer_write(ringbuffer[c], (const char*) converted, byte_length);
		}
		return src_data.input_frames_used * frame_size;
	} else {
#endif
		int byte_length = frames * sizeof(jack_default_audio_sample_t);
		for (int c = 0; c < CHANNELS; c++) {
			jack_ringbuffer_write(ringbuffer[c], (const char*) buf[c], byte_length);
		}

		return frames * frame_size;
#ifdef HAVE_SAMPLERATE
	}
#endif
}