diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/pulsecore/sample-util.c | 148 | ||||
| -rw-r--r-- | src/pulsecore/sample-util.h | 16 | 
2 files changed, 119 insertions, 45 deletions
diff --git a/src/pulsecore/sample-util.c b/src/pulsecore/sample-util.c index 4a532f29..bf1f7c26 100644 --- a/src/pulsecore/sample-util.c +++ b/src/pulsecore/sample-util.c @@ -42,28 +42,6 @@  #define PA_SILENCE_MAX (PA_PAGE_SIZE*16) -pa_memblock *pa_silence_memblock_new(pa_mempool *pool, const pa_sample_spec *spec, size_t length) { -    pa_memblock *b; - -    pa_assert(pool); -    pa_assert(spec); - -    if (length <= 0) -        length = PA_MIN(pa_bytes_per_second(spec)/20, /* 50 ms */ -                        pa_mempool_block_size_max(pool)); - -    if (length > PA_SILENCE_MAX) -        length = PA_SILENCE_MAX; - -    length = pa_frame_align(length, spec); - -    b = pa_silence_memblock(pa_memblock_new(pool, length), spec); - -    pa_memblock_set_is_silence(b, TRUE); - -    return b; -} -  pa_memblock *pa_silence_memblock(pa_memblock* b, const pa_sample_spec *spec) {      void *data; @@ -77,7 +55,7 @@ pa_memblock *pa_silence_memblock(pa_memblock* b, const pa_sample_spec *spec) {      return b;  } -void pa_silence_memchunk(pa_memchunk *c, const pa_sample_spec *spec) { +pa_memchunk* pa_silence_memchunk(pa_memchunk *c, const pa_sample_spec *spec) {      void *data;      pa_assert(c); @@ -87,37 +65,38 @@ void pa_silence_memchunk(pa_memchunk *c, const pa_sample_spec *spec) {      data = pa_memblock_acquire(c->memblock);      pa_silence_memory((uint8_t*) data+c->index, c->length, spec);      pa_memblock_release(c->memblock); -} -void pa_silence_memory(void *p, size_t length, const pa_sample_spec *spec) { -    uint8_t c = 0; -    pa_assert(p); -    pa_assert(length > 0); -    pa_assert(spec); +    return c; +} -    switch (spec->format) { +static uint8_t silence_byte(pa_sample_format_t format) { +    switch (format) {          case PA_SAMPLE_U8: -            c = 0x80; -            break; +            return 0x80;          case PA_SAMPLE_S16LE:          case PA_SAMPLE_S16BE:          case PA_SAMPLE_S32LE:          case PA_SAMPLE_S32BE: -        case PA_SAMPLE_FLOAT32: -        case PA_SAMPLE_FLOAT32RE: -            c = 0; -            break; +        case PA_SAMPLE_FLOAT32LE: +        case PA_SAMPLE_FLOAT32BE: +            return 0;          case PA_SAMPLE_ALAW: -            c = 0xd5; -            break; +            return 0xd5;          case PA_SAMPLE_ULAW: -            c = 0xff; -            break; +            return 0xff;          default:              pa_assert_not_reached();      } +    return 0; +} -    memset(p, c, length); +void* pa_silence_memory(void *p, size_t length, const pa_sample_spec *spec) { +    pa_assert(p); +    pa_assert(length > 0); +    pa_assert(spec); + +    memset(p, silence_byte(spec->format), length); +    return p;  }  static void calc_linear_integer_stream_volumes(pa_mix_info streams[], unsigned nstreams, const pa_sample_spec *spec) { @@ -934,3 +913,90 @@ void pa_deinterleave(const void *src, void *dst[], unsigned channels, size_t ss,          }      }  } + +static pa_memblock *silence_memblock_new(pa_mempool *pool, uint8_t c) { +    pa_memblock *b; +    size_t length; +    void *data; + +    pa_assert(pool); + +    length = PA_MIN(pa_mempool_block_size_max(pool), PA_SILENCE_MAX); + +    b = pa_memblock_new(pool, length); + +    data = pa_memblock_acquire(b); +    memset(data, c, length); +    pa_memblock_release(b); + +    pa_memblock_set_is_silence(b, TRUE); + +    return b; +} + +void pa_silence_cache_init(pa_silence_cache *cache) { +    pa_assert(cache); + +    memset(cache, 0, sizeof(pa_silence_cache)); +} + +void pa_silence_cache_done(pa_silence_cache *cache) { +    pa_sample_format_t f; +    pa_assert(cache); + +    for (f = 0; f < PA_SAMPLE_MAX; f++) +        if (cache->blocks[f]) +            pa_memblock_unref(cache->blocks[f]); + +    memset(cache, 0, sizeof(pa_silence_cache)); +} + +pa_memchunk* pa_silence_memchunk_get(pa_silence_cache *cache, pa_mempool *pool, pa_memchunk* ret, const pa_sample_spec *spec, size_t length) { +    pa_memblock *b; +    size_t l; + +    pa_assert(cache); +    pa_assert(pa_sample_spec_valid(spec)); + +    if (!(b = cache->blocks[spec->format])) + +        switch (spec->format) { +            case PA_SAMPLE_U8: +                cache->blocks[PA_SAMPLE_U8] = b = silence_memblock_new(pool, 0x80); +                break; +            case PA_SAMPLE_S16LE: +            case PA_SAMPLE_S16BE: +            case PA_SAMPLE_S32LE: +            case PA_SAMPLE_S32BE: +            case PA_SAMPLE_FLOAT32LE: +            case PA_SAMPLE_FLOAT32BE: +                cache->blocks[PA_SAMPLE_S16LE] = b = silence_memblock_new(pool, 0); +                cache->blocks[PA_SAMPLE_S16BE] = pa_memblock_ref(b); +                cache->blocks[PA_SAMPLE_S32LE] = pa_memblock_ref(b); +                cache->blocks[PA_SAMPLE_S32BE] = pa_memblock_ref(b); +                cache->blocks[PA_SAMPLE_FLOAT32LE] = pa_memblock_ref(b); +                cache->blocks[PA_SAMPLE_FLOAT32BE] = pa_memblock_ref(b); +                break; +            case PA_SAMPLE_ALAW: +                cache->blocks[PA_SAMPLE_ALAW] = b = silence_memblock_new(pool, 0xd5); +                break; +            case PA_SAMPLE_ULAW: +                cache->blocks[PA_SAMPLE_ULAW] = b = silence_memblock_new(pool, 0xff); +                break; +            default: +                pa_assert_not_reached(); +    } + +    pa_assert(b); + +    ret->memblock = pa_memblock_ref(b); + +    l = pa_memblock_get_length(b); +    if (length > l || length == 0) +        length = l; + +    ret->length = pa_frame_align(length, spec); +    ret->index = 0; + +    return ret; +} diff --git a/src/pulsecore/sample-util.h b/src/pulsecore/sample-util.h index 2ef8f924..45f00883 100644 --- a/src/pulsecore/sample-util.h +++ b/src/pulsecore/sample-util.h @@ -30,10 +30,18 @@  #include <pulsecore/memblock.h>  #include <pulsecore/memchunk.h> -pa_memblock *pa_silence_memblock(pa_memblock* b, const pa_sample_spec *spec); -pa_memblock *pa_silence_memblock_new(pa_mempool *pool, const pa_sample_spec *spec, size_t length); -void pa_silence_memchunk(pa_memchunk *c, const pa_sample_spec *spec); -void pa_silence_memory(void *p, size_t length, const pa_sample_spec *spec); +typedef struct pa_silence_cache { +    pa_memblock* blocks[PA_SAMPLE_MAX]; +} pa_silence_cache; + +void pa_silence_cache_init(pa_silence_cache *cache); +void pa_silence_cache_done(pa_silence_cache *cache); + +void *pa_silence_memory(void *p, size_t length, const pa_sample_spec *spec); +pa_memchunk* pa_silence_memchunk(pa_memchunk *c, const pa_sample_spec *spec); +pa_memblock* pa_silence_memblock(pa_memblock *b, const pa_sample_spec *spec); + +pa_memchunk* pa_silence_memchunk_get(pa_silence_cache *cache, pa_mempool *pool, pa_memchunk* ret, const pa_sample_spec *spec, size_t length);  typedef struct pa_mix_info {      pa_memchunk chunk;  | 
