*** 0.2 ***
-- pacat quit() ?
- several files: copyright and config.h
- enable searchdir
- future cancellation
- make mcalign merge chunks
- use ref counting in more objects
-- move the global memblock statistics variables to the core
- unix socket directories include user name
- native library/protocol:
module load/unload
static int pa_cli_command_stat(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose) {
assert(c && t);
- pa_strbuf_printf(buf, "Memory blocks allocated: %u, total size: %u bytes.\n", pa_memblock_get_count(), pa_memblock_get_total());
+ pa_strbuf_printf(buf, "Memory blocks currently allocated: %u, size: %u bytes.\nMemory blocks allocated during the whole lifetime: %u, size: %u bytes.\n", c->memblock_stat->total, c->memblock_stat->total_size, c->memblock_stat->allocated, c->memblock_stat->allocated_size);
return 0;
}
return -1;
}
- if (pa_sound_file_load(fname, &ss, &chunk) < 0) {
+ if (pa_sound_file_load(fname, &ss, &chunk, c->memblock_stat) < 0) {
pa_strbuf_puts(buf, "Failed to load sound file.\n");
return -1;
}
return -1;
}
- if (pa_sound_file_load(fname, &ss, &chunk) < 0) {
+ if (pa_sound_file_load(fname, &ss, &chunk, c->memblock_stat) < 0) {
pa_strbuf_puts(buf, "Failed to load sound file.\n");
return -1;
}
c->subscription_defer_event = NULL;
c->subscription_event_queue = NULL;
c->subscriptions = NULL;
+
+ c->memblock_stat = pa_memblock_stat_new();
pa_check_for_sigpipe();
pa_xfree(c->default_source_name);
pa_xfree(c->default_sink_name);
+
+ pa_memblock_stat_unref(c->memblock_stat);
pa_xfree(c);
};
#include "hashmap.h"
#include "mainloop-api.h"
#include "sample.h"
+#include "memblock.h"
struct pa_core {
struct pa_mainloop_api *mainloop;
struct pa_defer_event *subscription_defer_event;
struct pa_queue *subscription_event_queue;
struct pa_subscription *subscriptions;
+
+ struct pa_memblock_stat *memblock_stat;
};
struct pa_core* pa_core_new(struct pa_mainloop_api *m);
#include "memblock.h"
#include "xmalloc.h"
-static unsigned memblock_count = 0, memblock_total = 0;
+static void stat_add(struct pa_memblock*m, struct pa_memblock_stat *s) {
+ assert(m);
+
+ m->stat = pa_memblock_stat_ref(s);
+ s->total++;
+ s->allocated++;
+ s->total_size += m->length;
+ s->allocated_size += m->length;
+}
+
+static void stat_remove(struct pa_memblock *m) {
+ assert(m);
+
+ if (!m->stat)
+ return;
-struct pa_memblock *pa_memblock_new(size_t length) {
+ m->stat->total--;
+ m->stat->total_size -= m->length;
+
+ pa_memblock_stat_unref(m->stat);
+ m->stat = NULL;
+}
+
+struct pa_memblock *pa_memblock_new(size_t length, struct pa_memblock_stat*s) {
struct pa_memblock *b = pa_xmalloc(sizeof(struct pa_memblock)+length);
b->type = PA_MEMBLOCK_APPENDED;
b->ref = 1;
b->length = length;
b->data = b+1;
b->free_cb = NULL;
- memblock_count++;
- memblock_total += length;
+ stat_add(b, s);
return b;
}
-struct pa_memblock *pa_memblock_new_fixed(void *d, size_t length) {
+struct pa_memblock *pa_memblock_new_fixed(void *d, size_t length, struct pa_memblock_stat*s) {
struct pa_memblock *b = pa_xmalloc(sizeof(struct pa_memblock));
b->type = PA_MEMBLOCK_FIXED;
b->ref = 1;
b->length = length;
b->data = d;
b->free_cb = NULL;
- memblock_count++;
- memblock_total += length;
+ stat_add(b, s);
return b;
}
-struct pa_memblock *pa_memblock_new_dynamic(void *d, size_t length) {
+struct pa_memblock *pa_memblock_new_dynamic(void *d, size_t length, struct pa_memblock_stat*s) {
struct pa_memblock *b = pa_xmalloc(sizeof(struct pa_memblock));
b->type = PA_MEMBLOCK_DYNAMIC;
b->ref = 1;
b->length = length;
b->data = d;
b->free_cb = NULL;
- memblock_count++;
- memblock_total += length;
+ stat_add(b, s);
return b;
}
-struct pa_memblock *pa_memblock_new_user(void *d, size_t length, void (*free_cb)(void *p)) {
+struct pa_memblock *pa_memblock_new_user(void *d, size_t length, void (*free_cb)(void *p), struct pa_memblock_stat*s) {
struct pa_memblock *b;
assert(d && length && free_cb);
b = pa_xmalloc(sizeof(struct pa_memblock));
b->length = length;
b->data = d;
b->free_cb = free_cb;
- memblock_count++;
- memblock_total += length;
+ stat_add(b, s);
return b;
}
assert(b && b->ref >= 1);
if ((--(b->ref)) == 0) {
- memblock_count--;
- memblock_total -= b->length;
+ stat_remove(b);
if (b->type == PA_MEMBLOCK_USER) {
assert(b->free_cb);
}
}
-unsigned pa_memblock_get_count(void) {
- return memblock_count;
+struct pa_memblock_stat* pa_memblock_stat_new(void) {
+ struct pa_memblock_stat *s;
+
+ s = pa_xmalloc(sizeof(struct pa_memblock_stat));
+ s->ref = 1;
+ s->total = s->total_size = s->allocated = s->allocated_size = 0;
+
+ return s;
+}
+
+void pa_memblock_stat_unref(struct pa_memblock_stat *s) {
+ assert(s && s->ref >= 1);
+
+ if (!(--(s->ref))) {
+ assert(!s->total);
+ pa_xfree(s);
+ }
}
-unsigned pa_memblock_get_total(void) {
- return memblock_total;
+struct pa_memblock_stat * pa_memblock_stat_ref(struct pa_memblock_stat *s) {
+ assert(s);
+ s->ref++;
+ return s;
}
enum pa_memblock_type { PA_MEMBLOCK_FIXED, PA_MEMBLOCK_APPENDED, PA_MEMBLOCK_DYNAMIC, PA_MEMBLOCK_USER };
+struct pa_memblock_stat;
+
struct pa_memblock {
enum pa_memblock_type type;
unsigned ref;
size_t length;
void *data;
void (*free_cb)(void *p);
+ struct pa_memblock_stat *stat;
};
-struct pa_memblock *pa_memblock_new(size_t length);
-struct pa_memblock *pa_memblock_new_fixed(void *data, size_t length);
-struct pa_memblock *pa_memblock_new_dynamic(void *data, size_t length);
-struct pa_memblock *pa_memblock_new_user(void *data, size_t length, void (*free_cb)(void *p));
+struct pa_memblock *pa_memblock_new(size_t length, struct pa_memblock_stat*s);
+struct pa_memblock *pa_memblock_new_fixed(void *data, size_t length, struct pa_memblock_stat*s);
+struct pa_memblock *pa_memblock_new_dynamic(void *data, size_t length, struct pa_memblock_stat*s);
+struct pa_memblock *pa_memblock_new_user(void *data, size_t length, void (*free_cb)(void *p), struct pa_memblock_stat*s);
void pa_memblock_unref(struct pa_memblock*b);
struct pa_memblock* pa_memblock_ref(struct pa_memblock*b);
void pa_memblock_unref_fixed(struct pa_memblock*b);
-unsigned pa_memblock_get_count(void);
-unsigned pa_memblock_get_total(void);
+struct pa_memblock_stat {
+ int ref;
+ unsigned total;
+ unsigned total_size;
+ unsigned allocated;
+ unsigned allocated_size;
+};
+
+struct pa_memblock_stat* pa_memblock_stat_new(void);
+void pa_memblock_stat_unref(struct pa_memblock_stat *s);
+struct pa_memblock_stat * pa_memblock_stat_ref(struct pa_memblock_stat *s);
#endif
int measure_delay;
uint32_t delay;
struct pa_mcalign *mcalign;
+ struct pa_memblock_stat *memblock_stat;
};
-struct pa_memblockq* pa_memblockq_new(size_t maxlength, size_t tlength, size_t base, size_t prebuf, size_t minreq) {
+struct pa_memblockq* pa_memblockq_new(size_t maxlength, size_t tlength, size_t base, size_t prebuf, size_t minreq, struct pa_memblock_stat *s) {
struct pa_memblockq* bq;
assert(maxlength && base && maxlength);
bq->delay = 0;
bq->mcalign = NULL;
+
+ bq->memblock_stat = s;
return bq;
}
}
if (!bq->mcalign) {
- bq->mcalign = pa_mcalign_new(bq->base);
+ bq->mcalign = pa_mcalign_new(bq->base, bq->memblock_stat);
assert(bq->mcalign);
}
size_t tlength,
size_t base,
size_t prebuf,
- size_t minreq);
+ size_t minreq,
+ struct pa_memblock_stat *s);
void pa_memblockq_free(struct pa_memblockq*bq);
/* Push a new memory chunk into the queue. Optionally specify a value for future cancellation. This is currently not implemented, however! */
#include "memchunk.h"
#include "xmalloc.h"
-void pa_memchunk_make_writable(struct pa_memchunk *c) {
+void pa_memchunk_make_writable(struct pa_memchunk *c, struct pa_memblock_stat *s) {
struct pa_memblock *n;
assert(c && c->memblock && c->memblock->ref >= 1);
if (c->memblock->ref == 1)
return;
- n = pa_memblock_new(c->length);
+ n = pa_memblock_new(c->length, s);
assert(n);
memcpy(n->data, c->memblock->data+c->index, c->length);
pa_memblock_unref(c->memblock);
struct pa_memchunk chunk;
uint8_t *buffer;
size_t buffer_fill;
+ struct pa_memblock_stat *memblock_stat;
};
-struct pa_mcalign *pa_mcalign_new(size_t base) {
+struct pa_mcalign *pa_mcalign_new(size_t base, struct pa_memblock_stat *s) {
struct pa_mcalign *m;
assert(base);
m->chunk.length = m->chunk.index = 0;
m->buffer = NULL;
m->buffer_fill = 0;
+ m->memblock_stat = s;
return m;
}
assert(m->buffer_fill <= m->base);
if (m->buffer_fill == m->base) {
- c->memblock = pa_memblock_new_dynamic(m->buffer, m->base);
+ c->memblock = pa_memblock_new_dynamic(m->buffer, m->base, m->memblock_stat);
assert(c->memblock);
c->index = 0;
c->length = m->base;
size_t index, length;
};
-void pa_memchunk_make_writable(struct pa_memchunk *c);
+void pa_memchunk_make_writable(struct pa_memchunk *c, struct pa_memblock_stat *s);
struct pa_mcalign;
-struct pa_mcalign *pa_mcalign_new(size_t base);
+struct pa_mcalign *pa_mcalign_new(size_t base, struct pa_memblock_stat *s);
void pa_mcalign_free(struct pa_mcalign *m);
void pa_mcalign_push(struct pa_mcalign *m, const struct pa_memchunk *c);
int pa_mcalign_pop(struct pa_mcalign *m, struct pa_memchunk *c);
fprintf(stderr, __FILE__": using %u fragments of size %u bytes.\n", periods, u->fragment_size);
- u->silence.memblock = pa_memblock_new(u->silence.length = u->fragment_size);
+ u->silence.memblock = pa_memblock_new(u->silence.length = u->fragment_size, c->memblock_stat);
assert(u->silence.memblock);
pa_silence_memblock(u->silence.memblock, &ss);
u->silence.index = 0;
size_t l;
if (!u->memchunk.memblock) {
- u->memchunk.memblock = pa_memblock_new(u->memchunk.length = u->fragment_size);
+ u->memchunk.memblock = pa_memblock_new(u->memchunk.length = u->fragment_size, u->source->core->memblock_stat);
u->memchunk.index = 0;
}
if (u->out_memblocks[u->out_current])
pa_memblock_unref_fixed(u->out_memblocks[u->out_current]);
- chunk.memblock = u->out_memblocks[u->out_current] = pa_memblock_new_fixed(u->out_mmap+u->out_fragment_size*u->out_current, u->out_fragment_size);
+ chunk.memblock = u->out_memblocks[u->out_current] = pa_memblock_new_fixed(u->out_mmap+u->out_fragment_size*u->out_current, u->out_fragment_size, u->core->memblock_stat);
assert(chunk.memblock);
chunk.length = chunk.memblock->length;
chunk.index = 0;
struct pa_memchunk chunk;
if (!u->in_memblocks[u->in_current]) {
- chunk.memblock = u->in_memblocks[u->in_current] = pa_memblock_new_fixed(u->in_mmap+u->in_fragment_size*u->in_current, u->in_fragment_size);
+ chunk.memblock = u->in_memblocks[u->in_current] = pa_memblock_new_fixed(u->in_mmap+u->in_fragment_size*u->in_current, u->in_fragment_size, u->core->memblock_stat);
chunk.length = chunk.memblock->length;
chunk.index = 0;
update_usage(u);
- memchunk.memblock = pa_memblock_new(u->in_fragment_size);
+ memchunk.memblock = pa_memblock_new(u->in_fragment_size, u->core->memblock_stat);
assert(memchunk.memblock);
if ((r = pa_iochannel_read(u->io, memchunk.memblock->data, memchunk.memblock->length)) < 0) {
pa_memblock_unref(memchunk.memblock);
u->out_fragment_size = out_frag_size;
u->in_fragment_size = in_frag_size;
- u->silence.memblock = pa_memblock_new(u->silence.length = u->out_fragment_size);
+ u->silence.memblock = pa_memblock_new(u->silence.length = u->out_fragment_size, u->core->memblock_stat);
assert(u->silence.memblock);
pa_silence_memblock(u->silence.memblock, &ss);
u->silence.index = 0;
return;
}
- fprintf(stderr, "Currently in use: %u blocks containing %u bytes total.\n", i->memblock_count, i->memblock_total);
+ fprintf(stderr, "Currently in use: %u blocks containing %u bytes total.\n"
+ "Allocated during whole lifetime: %u blocks containing %u bytes total.\n",
+ i->memblock_total, i->memblock_total_size, i->memblock_allocated, i->memblock_allocated_size);
drain();
}
c->subscribe_callback = NULL;
c->subscribe_userdata = NULL;
+ c->memblock_stat = pa_memblock_stat_new();
+
pa_check_for_sigpipe();
return c;
}
pa_dynarray_free(c->record_streams, NULL, NULL);
if (c->playback_streams)
pa_dynarray_free(c->playback_streams, NULL, NULL);
-
+
+ pa_memblock_stat_unref(c->memblock_stat);
+
pa_xfree(c->name);
pa_xfree(c);
}
}
assert(!c->pstream);
- c->pstream = pa_pstream_new(c->mainloop, io);
+ c->pstream = pa_pstream_new(c->mainloop, io, c->memblock_stat);
assert(c->pstream);
pa_pstream_set_die_callback(c->pstream, pstream_die_callback, c);
void (*subscribe_callback)(struct pa_context *c, enum pa_subscription_event_type t, uint32_t index, void *userdata);
void *subscribe_userdata;
+
+ struct pa_memblock_stat *memblock_stat;
};
struct pa_stream {
goto finish;
p = NULL;
- } else if (pa_tagstruct_getu32(t, &i.memblock_count) < 0 ||
- pa_tagstruct_getu32(t, &i.memblock_total) < 0 ||
+ } else if (pa_tagstruct_getu32(t, &i.memblock_total) < 0 ||
+ pa_tagstruct_getu32(t, &i.memblock_total_size) < 0 ||
+ pa_tagstruct_getu32(t, &i.memblock_allocated) < 0 ||
+ pa_tagstruct_getu32(t, &i.memblock_allocated_size) < 0 ||
!pa_tagstruct_eof(t)) {
pa_context_fail(o->context, PA_ERROR_PROTOCOL);
goto finish;
/** Memory block statistics */
struct pa_stat_info {
- uint32_t memblock_count; /**< Allocated memory blocks */
- uint32_t memblock_total; /**< Total size of allocated memory blocks */
+ uint32_t memblock_total; /**< Currently allocated memory blocks */
+ uint32_t memblock_total_size; /**< Currentl total size of allocated memory blocks */
+ uint32_t memblock_allocated; /**< Allocated memory blocks during the whole lifetime of the daemon */
+ uint32_t memblock_allocated_size; /**< Total size of all memory blocks allocated during the whole lifetime of the daemon */
};
/** Get daemon memory block statistics */
assert(s && s->context && data && length && s->state == PA_STREAM_READY && s->ref >= 1);
if (free_cb) {
- chunk.memblock = pa_memblock_new_user((void*) data, length, free_cb);
+ chunk.memblock = pa_memblock_new_user((void*) data, length, free_cb, s->context->memblock_stat);
assert(chunk.memblock && chunk.memblock->data);
} else {
- chunk.memblock = pa_memblock_new(length);
+ chunk.memblock = pa_memblock_new(length, s->context->memblock_stat);
assert(chunk.memblock && chunk.memblock->data);
memcpy(chunk.memblock->data, data, length);
}
assert(!c->input_memblockq);
l = (size_t) (pa_bytes_per_second(&ss)*PLAYBACK_BUFFER_SECONDS);
- c->input_memblockq = pa_memblockq_new(l, 0, pa_frame_size(&ss), l/2, l/PLAYBACK_BUFFER_FRAGMENTS);
+ c->input_memblockq = pa_memblockq_new(l, 0, pa_frame_size(&ss), l/2, l/PLAYBACK_BUFFER_FRAGMENTS, c->protocol->core->memblock_stat);
assert(c->input_memblockq);
pa_iochannel_socket_set_rcvbuf(c->io, l/PLAYBACK_BUFFER_FRAGMENTS*2);
c->playback.fragment_size = l/10;
assert(!c->output_memblockq);
l = (size_t) (pa_bytes_per_second(&ss)*RECORD_BUFFER_SECONDS);
- c->output_memblockq = pa_memblockq_new(l, 0, pa_frame_size(&ss), 0, 0);
+ c->output_memblockq = pa_memblockq_new(l, 0, pa_frame_size(&ss), 0, 0, c->protocol->core->memblock_stat);
assert(c->output_memblockq);
pa_iochannel_socket_set_sndbuf(c->io, l/RECORD_BUFFER_FRAGMENTS*2);
name[sizeof(name)-1] = 0;
assert(!c->scache_memchunk.memblock);
- c->scache_memchunk.memblock = pa_memblock_new(sc_length);
+ c->scache_memchunk.memblock = pa_memblock_new(sc_length, c->protocol->core->memblock_stat);
c->scache_memchunk.index = 0;
c->scache_memchunk.length = sc_length;
c->scache_sample_spec = ss;
}
if (!c->playback.current_memblock) {
- c->playback.current_memblock = pa_memblock_new(c->playback.fragment_size*2);
+ c->playback.current_memblock = pa_memblock_new(c->playback.fragment_size*2, c->protocol->core->memblock_stat);
assert(c->playback.current_memblock && c->playback.current_memblock->length >= l);
c->playback.memblock_index = 0;
}
s->source_output->owner = c->protocol->module;
s->source_output->client = c->client;
- s->memblockq = pa_memblockq_new(maxlength, 0, base = pa_frame_size(ss), 0, 0);
+ s->memblockq = pa_memblockq_new(maxlength, 0, base = pa_frame_size(ss), 0, 0, c->protocol->core->memblock_stat);
assert(s->memblockq);
s->fragment_size = (fragment_size/base)*base;
s->sink_input->owner = c->protocol->module;
s->sink_input->client = c->client;
- s->memblockq = pa_memblockq_new(maxlength, tlength, pa_frame_size(ss), prebuf, minreq);
+ s->memblockq = pa_memblockq_new(maxlength, tlength, pa_frame_size(ss), prebuf, minreq, c->protocol->core->memblock_stat);
assert(s->memblockq);
s->requested_bytes = 0;
assert(reply);
pa_tagstruct_putu32(reply, PA_COMMAND_REPLY);
pa_tagstruct_putu32(reply, tag);
- pa_tagstruct_putu32(reply, pa_memblock_get_count());
- pa_tagstruct_putu32(reply, pa_memblock_get_total());
+ pa_tagstruct_putu32(reply, c->protocol->core->memblock_stat->total);
+ pa_tagstruct_putu32(reply, c->protocol->core->memblock_stat->total_size);
+ pa_tagstruct_putu32(reply, c->protocol->core->memblock_stat->allocated);
+ pa_tagstruct_putu32(reply, c->protocol->core->memblock_stat->allocated_size);
pa_pstream_send_tagstruct(c->pstream, reply);
}
u->length = 0;
fprintf(stderr, "COPY\n");
} else {
- u->memchunk.memblock = pa_memblock_new(u->length);
+ u->memchunk.memblock = pa_memblock_new(u->length, c->protocol->core->memblock_stat);
u->memchunk.index = u->memchunk.length = 0;
}
}
c->client->userdata = c;
c->client->owner = p->module;
- c->pstream = pa_pstream_new(p->core->mainloop, io);
+ c->pstream = pa_pstream_new(p->core->mainloop, io, p->core->memblock_stat);
assert(c->pstream);
pa_pstream_set_recieve_packet_callback(c->pstream, pstream_packet_callback, c);
}
if (!c->playback.current_memblock) {
- c->playback.current_memblock = pa_memblock_new(c->playback.fragment_size*2);
+ c->playback.current_memblock = pa_memblock_new(c->playback.fragment_size*2, c->protocol->core->memblock_stat);
assert(c->playback.current_memblock && c->playback.current_memblock->length >= l);
c->playback.memblock_index = 0;
}
c->sink_input->userdata = c;
l = (size_t) (pa_bytes_per_second(&p->sample_spec)*PLAYBACK_BUFFER_SECONDS);
- c->input_memblockq = pa_memblockq_new(l, 0, pa_frame_size(&p->sample_spec), l/2, l/PLAYBACK_BUFFER_FRAGMENTS);
+ c->input_memblockq = pa_memblockq_new(l, 0, pa_frame_size(&p->sample_spec), l/2, l/PLAYBACK_BUFFER_FRAGMENTS, p->core->memblock_stat);
assert(c->input_memblockq);
pa_iochannel_socket_set_rcvbuf(io, l/PLAYBACK_BUFFER_FRAGMENTS*5);
c->playback.fragment_size = l/10;
c->source_output->userdata = c;
l = (size_t) (pa_bytes_per_second(&p->sample_spec)*RECORD_BUFFER_SECONDS);
- c->output_memblockq = pa_memblockq_new(l, 0, pa_frame_size(&p->sample_spec), 0, 0);
+ c->output_memblockq = pa_memblockq_new(l, 0, pa_frame_size(&p->sample_spec), 0, 0, p->core->memblock_stat);
pa_iochannel_socket_set_sndbuf(io, l/RECORD_BUFFER_FRAGMENTS*2);
}
void (*drain_callback)(struct pa_pstream *p, void *userdata);
void *drain_userdata;
+
+ struct pa_memblock_stat *memblock_stat;
};
static void do_write(struct pa_pstream *p);
do_something(p);
}
-struct pa_pstream *pa_pstream_new(struct pa_mainloop_api *m, struct pa_iochannel *io) {
+struct pa_pstream *pa_pstream_new(struct pa_mainloop_api *m, struct pa_iochannel *io, struct pa_memblock_stat *s) {
struct pa_pstream *p;
assert(io);
p->drain_callback = NULL;
p->drain_userdata = NULL;
+ p->memblock_stat = s;
+
return p;
}
p->read.data = p->read.packet->data;
} else {
/* Frame is a memblock frame */
- p->read.memblock = pa_memblock_new(ntohl(p->read.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH]));
+ p->read.memblock = pa_memblock_new(ntohl(p->read.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH]), p->memblock_stat);
assert(p->read.memblock);
p->read.data = p->read.memblock->data;
}
struct pa_pstream;
-struct pa_pstream* pa_pstream_new(struct pa_mainloop_api *m, struct pa_iochannel *io);
+struct pa_pstream* pa_pstream_new(struct pa_mainloop_api *m, struct pa_iochannel *io, struct pa_memblock_stat *s);
void pa_pstream_unref(struct pa_pstream*p);
struct pa_pstream* pa_pstream_ref(struct pa_pstream*p);
pa_convert_to_float32_func_t to_float32_func;
pa_convert_from_float32_func_t from_float32_func;
SRC_STATE *src_state;
+
+ struct pa_memblock_stat *memblock_stat;
};
-struct pa_resampler* pa_resampler_new(const struct pa_sample_spec *a, const struct pa_sample_spec *b) {
+struct pa_resampler* pa_resampler_new(const struct pa_sample_spec *a, const struct pa_sample_spec *b, struct pa_memblock_stat *s) {
struct pa_resampler *r = NULL;
int err;
assert(a && b && pa_sample_spec_valid(a) && pa_sample_spec_valid(b));
r->from_float32_func = pa_get_convert_from_float32_function(b->format);
assert(r->to_float32_func && r->from_float32_func);
+
+ r->memblock_stat = s;
return r;
eff_ons = ons;
}
- out->memblock = pa_memblock_new(out->length = (ons*r->o_sz));
+ out->memblock = pa_memblock_new(out->length = (ons*r->o_sz), r->memblock_stat);
out->index = 0;
assert(out->memblock);
struct pa_resampler;
-struct pa_resampler* pa_resampler_new(const struct pa_sample_spec *a, const struct pa_sample_spec *b);
+struct pa_resampler* pa_resampler_new(const struct pa_sample_spec *a, const struct pa_sample_spec *b, struct pa_memblock_stat *s);
void pa_resampler_free(struct pa_resampler *r);
size_t pa_resampler_request(struct pa_resampler *r, size_t out_length);
assert(s && spec);
if (!pa_sample_spec_equal(spec, &s->sample_spec))
- if (!(resampler = pa_resampler_new(spec, &s->sample_spec)))
+ if (!(resampler = pa_resampler_new(spec, &s->sample_spec, s->core->memblock_stat)))
return NULL;
i = pa_xmalloc(sizeof(struct pa_sink_input));
volume = pa_volume_multiply(s->volume, info[0].volume);
if (volume != PA_VOLUME_NORM) {
- pa_memchunk_make_writable(result);
+ pa_memchunk_make_writable(result, s->core->memblock_stat);
pa_volume_memchunk(result, &s->sample_spec, volume);
}
} else {
- result->memblock = pa_memblock_new(length);
+ result->memblock = pa_memblock_new(length, s->core->memblock_stat);
assert(result->memblock);
result->length = l = pa_mix(info, n, result->memblock->data, length, &s->sample_spec, s->volume);
#define MAX_FILE_SIZE (1024*1024)
-int pa_sound_file_load(const char *fname, struct pa_sample_spec *ss, struct pa_memchunk *chunk) {
+int pa_sound_file_load(const char *fname, struct pa_sample_spec *ss, struct pa_memchunk *chunk, struct pa_memblock_stat *s) {
SNDFILE*sf = NULL;
SF_INFO sfinfo;
int ret = -1;
goto finish;
}
- chunk->memblock = pa_memblock_new(l);
+ chunk->memblock = pa_memblock_new(l, s);
assert(chunk->memblock);
chunk->index = 0;
chunk->length = l;
#include "memchunk.h"
#include "sample.h"
-int pa_sound_file_load(const char *fname, struct pa_sample_spec *ss, struct pa_memchunk *chunk);
+int pa_sound_file_load(const char *fname, struct pa_sample_spec *ss, struct pa_memchunk *chunk, struct pa_memblock_stat *s);
#endif
assert(s && spec);
if (!pa_sample_spec_equal(&s->sample_spec, spec))
- if (!(resampler = pa_resampler_new(&s->sample_spec, spec)))
+ if (!(resampler = pa_resampler_new(&s->sample_spec, spec, s->core->memblock_stat)))
return NULL;
o = pa_xmalloc(sizeof(struct pa_source_output));