mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-04 13:29:59 -05:00
add resampling
git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@45 fefdeb5f-60dc-0310-8127-8f9354f1896f
This commit is contained in:
parent
13b35a2489
commit
741aa44ffc
26 changed files with 251 additions and 115 deletions
|
|
@ -6,11 +6,18 @@
|
|||
#include "strbuf.h"
|
||||
#include "sample-util.h"
|
||||
|
||||
struct sink_input* sink_input_new(struct sink *s, struct pa_sample_spec *spec, const char *name) {
|
||||
#define CONVERT_BUFFER_LENGTH 4096
|
||||
|
||||
struct sink_input* sink_input_new(struct sink *s, const char *name, const struct pa_sample_spec *spec) {
|
||||
struct sink_input *i;
|
||||
struct resampler *resampler = NULL;
|
||||
int r;
|
||||
assert(s && spec);
|
||||
|
||||
if (!pa_sample_spec_equal(spec, &s->sample_spec))
|
||||
if (!(resampler = resampler_new(spec, &s->sample_spec)))
|
||||
return NULL;
|
||||
|
||||
i = malloc(sizeof(struct sink_input));
|
||||
assert(i);
|
||||
i->name = name ? strdup(name) : NULL;
|
||||
|
|
@ -25,12 +32,16 @@ struct sink_input* sink_input_new(struct sink *s, struct pa_sample_spec *spec, c
|
|||
|
||||
i->volume = VOLUME_NORM;
|
||||
|
||||
i->resampled_chunk.memblock = NULL;
|
||||
i->resampled_chunk.index = i->resampled_chunk.length = 0;
|
||||
i->resampler = resampler;
|
||||
|
||||
assert(s->core);
|
||||
r = idxset_put(s->core->sink_inputs, i, &i->index);
|
||||
assert(r == 0 && i->index != IDXSET_INVALID);
|
||||
r = idxset_put(s->inputs, i, NULL);
|
||||
assert(r == 0);
|
||||
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
|
|
@ -40,6 +51,11 @@ void sink_input_free(struct sink_input* i) {
|
|||
assert(i->sink && i->sink->core);
|
||||
idxset_remove_by_data(i->sink->core->sink_inputs, i, NULL);
|
||||
idxset_remove_by_data(i->sink->inputs, i, NULL);
|
||||
|
||||
if (i->resampled_chunk.memblock)
|
||||
memblock_unref(i->resampled_chunk.memblock);
|
||||
if (i->resampler)
|
||||
resampler_free(i->resampler);
|
||||
|
||||
free(i->name);
|
||||
free(i);
|
||||
|
|
@ -89,3 +105,53 @@ uint32_t sink_input_get_latency(struct sink_input *i) {
|
|||
return l;
|
||||
}
|
||||
|
||||
|
||||
int sink_input_peek(struct sink_input *i, struct memchunk *chunk) {
|
||||
assert(i && chunk && i->peek && i->drop);
|
||||
|
||||
if (!i->resampler)
|
||||
return i->peek(i, chunk);
|
||||
|
||||
if (!i->resampled_chunk.memblock) {
|
||||
struct memchunk tchunk;
|
||||
size_t l;
|
||||
int ret;
|
||||
|
||||
if ((ret = i->peek(i, &tchunk)) < 0)
|
||||
return ret;
|
||||
|
||||
l = resampler_request(i->resampler, CONVERT_BUFFER_LENGTH);
|
||||
if (tchunk.length > l)
|
||||
tchunk.length = l;
|
||||
|
||||
i->drop(i, tchunk.length);
|
||||
|
||||
resampler_run(i->resampler, &tchunk, &i->resampled_chunk);
|
||||
memblock_unref(tchunk.memblock);
|
||||
}
|
||||
|
||||
assert(i->resampled_chunk.memblock && i->resampled_chunk.length);
|
||||
*chunk = i->resampled_chunk;
|
||||
memblock_ref(i->resampled_chunk.memblock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sink_input_drop(struct sink_input *i, size_t length) {
|
||||
assert(i && length);
|
||||
|
||||
if (!i->resampler) {
|
||||
i->drop(i, length);
|
||||
return;
|
||||
}
|
||||
|
||||
assert(i->resampled_chunk.memblock && i->resampled_chunk.length >= length);
|
||||
|
||||
i->resampled_chunk.index += length;
|
||||
i->resampled_chunk.length -= length;
|
||||
|
||||
if (!i->resampled_chunk.length) {
|
||||
memblock_unref(i->resampled_chunk.memblock);
|
||||
i->resampled_chunk.memblock = NULL;
|
||||
i->resampled_chunk.index = i->resampled_chunk.length = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue