diff options
Diffstat (limited to 'src')
52 files changed, 10119 insertions, 0 deletions
| diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..bd82b1f --- /dev/null +++ b/src/Makefile @@ -0,0 +1,47 @@ +CFLAGS=-Wall -O0 -g -W -Wno-unused-parameter `pkg-config --cflags liboil-0.3` -DRANDOM_PREFIX=saspeex -DOUTSIDE_SPEEX -D_GNU_SOURCE -pthread +LIBS=-lm `pkg-config --libs liboil-0.3` + +SOURCES=common.c malloc.c oss.c bbuffer.c format.c volscale.c byteswap.c continued-fraction.c zero.c add.c speex/resample.c resample.c interleave.c converter.c g711.c mutex.c once.c thread.c bufferq.c # asyncq.c +OBJS=$(SOURCES:.c=.o) + +all: test-bufferq test-llist test-sine test-pull #test-asyncq + +test-bufferq: test-bufferq.o bufferq.o malloc.o #$(OBJS)  +	$(CC) $(CFLAGS) -o $@ $^ $(LIBS) + +test-llist: test-llist.o +	$(CC) $(CFLAGS) -o $@ $^ $(LIBS) + +test-sine: $(OBJS) test-sine.o +	$(CC) $(CFLAGS) -o $@ $^ $(LIBS) + +test-pull: $(OBJS) test-pull.o +	$(CC) $(CFLAGS) -o $@ $^ $(LIBS) + +test-asyncq: $(OBJS) test-asyncq.o +	$(CC) $(CFLAGS) -o $@ $^ $(LIBS) + +*.o: *.h + +indent: +	indent -bdfa -brf -kr -nbbo -nbc -ip0 -ppi 4 -cs -nbfde -npsl -br -brs -bap -i4 -bs -cdw -ce -npcs -hnl -cli4 -nut -ci8 < oss.c +#	astyle --indent=spaces=4 --brackets=attach --indent-switches  --max-instatement-indent=40 --pad=oper --unpad=paren --convert-tabs --mode=c < oss.c + +clean: +	rm -f *.o meta-name-table.h test-bufferq test-llist test-sine core test-pull speex/*.o + +common.o: meta-name-table.h + +meta-name-table.h: meta-name-table.gperf Makefile +	gperf -t -N sa_lookup_meta_name -H sa_hash_meta_name -p -C < $< | sed -e 's/{""}/{"", 0}/g' > $@ + +fixme: +	find -name '*.c' -exec fgrep -H -A 3 -B 3 -i FIXME \{\} \; + +update-speex: +	wget -O speex/speex_resampler.h http://svn.xiph.org/trunk/speex/include/speex/speex_resampler.h +	wget -O speex/resample.c http://svn.xiph.org/trunk/speex/libspeex/resample.c +	wget -O speex/arch.h http://svn.xiph.org/trunk/speex/libspeex/arch.h + +warn-export: all +	nm test-bufferq test-llist test-sine test-pull | grep " T " | awk '{print $$3}' | sort | uniq diff --git a/src/TODO b/src/TODO new file mode 100644 index 0000000..f12bf79 --- /dev/null +++ b/src/TODO @@ -0,0 +1,29 @@ +* Replace all "input", "output" with "read", "write" +* Vielleicht client_name nicht erzwingen, stattdessen /proc/self/exename nehmen o.ä. +* "adjust" channel map +* volume bei codecs? +* non-interleaved "int channel" -> "data[]" +* 24bit = 3 byte? 4 byte? + + +* real playback model +* threaded model + +* alsa +* jack +* pulse +* windows + + + +* s/sa_/syd_/g + +* vbr + +* should we notify about local volume changes?  + +* drop the ability to query the current write index? + +* drop pread + +* stop thread diff --git a/src/add.c b/src/add.c new file mode 100644 index 0000000..b7714f4 --- /dev/null +++ b/src/add.c @@ -0,0 +1,51 @@ +#include <liboil/liboil.h> + +#include "macro.h" +#include "add.h" + +static void add_u8(void *dst, size_t dstr, const void *src1, size_t sstr1, const void *src2, size_t sstr2, size_t bytes) { +    uint8_t *d = dst; +    const uint8_t *s1 = src1, *s2 = src2; + +    for (; bytes > 0; bytes--, d += dstr, s1 += sstr1, s2 += sstr2) { +        int16_t v = (int16_t) *s1 + (int16_t) *s2 - 0x80; + +        v = CLAMP(v, 0, 0xFF); +        *d = (uint8_t) v; +    } +} + +static void add_s16(void *dst, size_t dstr, const void *src1, size_t sstr1, const void *src2, size_t sstr2, size_t bytes) { +    oil_vectoradd_s_s16(dst, dstr, src1, sstr1, src2, sstr2, bytes/sizeof(int16_t)); +} + +static void add_s32(void *dst, size_t dstr, const void *src1, size_t sstr1, const void *src2, size_t sstr2, size_t bytes) { +    int32_t *d = dst; +    const int32_t *s1 = src1, *s2 = src2; + +    for (; bytes > 0; bytes--, d += dstr/sizeof(int32_t), s1 += sstr1/sizeof(int32_t), s2 += sstr2/sizeof(int32_t)) { +        int64_t v = (int64_t) *s1 + (uint64_t) *s2; + +        v = CLAMP(v, -0x80000000, 0x7FFFFFFF); +        *d = (int32_t) v; +    } +} + +static void add_f32(void *dst, size_t dstr, const void *src1, size_t sstr1, const void *src2, size_t sstr2, size_t bytes) { +    float a = 1, b = 1; +    oil_vectoradd_f32(dst, dstr, src1, sstr1, src2, sstr2, bytes/sizeof(int32_t), &a, &b); +} + +sa_add_func_t sa_get_add_func(sa_pcm_format_t f) { + +    static const sa_add_func_t funcs[_SA_PCM_FORMAT_MAX] = { +        [SA_PCM_FORMAT_U8] = add_u8, +        [SA_PCM_FORMAT_S16_NE] = add_s16, +        [SA_PCM_FORMAT_S32_NE] = add_s32, +        [SA_PCM_FORMAT_FLOAT32_NE] = add_f32 +    }; + +    sa_assert(f < _SA_PCM_FORMAT_MAX); + +    return funcs[f]; +} diff --git a/src/add.h b/src/add.h new file mode 100644 index 0000000..6a31bc5 --- /dev/null +++ b/src/add.h @@ -0,0 +1,13 @@ +#ifndef foosydneyaddhfoo +#define foosydneyaddhfoo + +#include <sys/types.h> +#include <inttypes.h> + +#include "sydney.h" + +typedef void (*sa_add_func_t) (void *dst, size_t dstr, const void *src1, size_t sstr1, const void *src2, size_t sstr2, size_t bytes); + +sa_add_func_t sa_get_add_func(sa_pcm_format_t f); + +#endif diff --git a/src/asyncq.c b/src/asyncq.c new file mode 100644 index 0000000..54d7d5b --- /dev/null +++ b/src/asyncq.c @@ -0,0 +1,102 @@ +#include "sydney.h" +#include "asyncq.h" +#include "malloc.h" + +int sa_asyncq_init(sa_asyncq_t *a, size_t item_size) { +    sa_assert(a); + +    SA_LLIST_HEAD_INIT(sa_asyncq_item_t, a->items); +    SA_LLIST_HEAD_INIT(sa_asyncq_item_t, a->unused); + +    a->last = NULL; +    a->item_size = item_size; +     +    if (!(a->mutex = sa_mutex_new(0))) +        return SA_ERROR_OOM; + +    return SA_SUCCESS; +} + +sa_asyncq_item_t *sa_asyncq_get(sa_asyncq_t *a) { +    sa_assert(a); +     +    sa_mutex_lock(a->mutex); + +    if ((i = a->unused)) +        SA_LLIST_REMOVE(sa_asyncq_item_t, items, a->unused, i); + +    sa_mutex_unlock(a->mutex); + +    if (!i) +        if (!(i = sa_malloc(SA_ALIGN(sa_asyncq_item_t) + a->item_size))) +            return NULL; + +    return i; +} + +void sa_asyncq_recycle(sa_asyncq_t *a, sa_asyncq_item_t *i) { +    sa_assert(a); +    sa_assert(i); + +    sa_mutex_lock(a->mutex); +    SA_LLIST_PREPEND(sa_asyncq_item_t, items, a->unused, i); +    sa_mutex_unlock(a->mutex); +} + +void sa_asyncq_push(sa_asyncq_t *a, sa_asyncq_item_t *i) { +    sa_assert(a); +    sa_assert(i); + +    sa_mutex_lock(a->mutex); + +    if (a->last) +        SA_LLIST_INSERT_AFTER(sa_asyncq_item_t, items, a->items, a->last, i); +    else +        SA_LLIST_PREPEND(sa_asyncq_item_t, items, a->items, i); +     +    a->last = i; + +    sa_mutex_unlock(a->mutex); + +    return SA_SUCCESS; +} + +sa_asyncq_item_t sa_asyncq_pop(sa_asyncq_t *a, int wait) { +    sa_asyncq_item_t *i; +     +    sa_assert(a); + +    if (wait) +        sa_mutex_lock(a->mutex); +    else +        if (!sa_mutex_try_lock(a->mutex)) +            return NULL; + +    if ((i = a->items)) { +        if (i == a->last) +            a->last = NULL; +         +        SA_LLIST_REMOVE(sa_asyncq_item_t, items, a->items, i); +    } +     +    sa_mutex_unlock(a->mutex); + +    return i; +} + +void sa_asyncq_done(sa_asyncq_t *a) { +    sa_asyncq_item_t *i; +    sa_assert(a); + +    /* The caller *must* pop all items from the queue before +     * destructing us! */ +    sa_assert(!a->items); +     +    if (a->mutex) +        sa_mutex_free(a->mutex); + +    while ((i = a->unused)) { +        SA_LLIST_REMOVE(sa_asyncq_item_t, items, a->unused, i); +        sa_free(i); +    } +} diff --git a/src/asyncq.h b/src/asyncq.h new file mode 100644 index 0000000..2e60c23 --- /dev/null +++ b/src/asyncq.h @@ -0,0 +1,49 @@ +#ifndef foosydneyhasynchfoo +#define foosydneyhasynchfoo + +#include "llist.h" +#include "mutex.h" + +typedef struct sa_asyncq sa_asyncq_t; +typedef struct sa_asyncq_item sa_asyncq_item_t; + +struct sa_asyncq_item { +    SA_LLIST_ITEM(sa_asyncq_item_t, items); +}; + +#define SA_ASYNCQ_ITEM_DATA(x) ((void*) ((uint8_t*) (x) + ALIGN(sizeof(sa_asyncq_item_t)))) + +struct sa_asyncq { +    sa_mutex_t *mutex; + +    SA_LLIST_HEAD(sa_asyncq_item_t, items); +    SA_LLIST_HEAD(sa_asyncq_item_t, unused); + +    sa_asyncq_item_t *last; + +    size_t item_size; +}; + +/* Implements a simple asynchronous queue for + * inter-thread-communication. To reading side can act in a wait-free + * fashion (though not lock-free). Should only be used together with a + * non-sychrnoized backing buffer such as sa_bufferq. */ + +int sa_asyncq_init(sa_asyncq_t *a, size_t item_size); + +void sa_asyncq_done(sa_asyncq_t *a); + +/* Allocate a free queue item */ +sa_asyncq_item_t *sa_asyncq_get(sa_asyncq_t *a); + +/* Give the queue item back to the queue */ +void sa_asyncq_recycle(sa_asyncq_t *a); + +/* Push a previously allocated entry into the queue */ +void sa_asyncq_push(sa_asyncq_t *a, sa_asyncq_item_t *i); + +/* Pop an entry from the queue */ +sa_asyncq_item_t* sa_asyncq_pop(sa_asyncq_t *a, int wait); + + +#endif diff --git a/src/bbuffer.c b/src/bbuffer.c new file mode 100644 index 0000000..c8cbaa0 --- /dev/null +++ b/src/bbuffer.c @@ -0,0 +1,77 @@ +#include <sys/types.h> + +#include "bbuffer.h" +#include "sydney.h" +#include "malloc.h" +#include "macro.h" + +int sa_bbuffer_init(sa_bbuffer_t *b, unsigned nchannels, size_t sample_size) { +    sa_assert(b); +    sa_assert(nchannels > 0); +    sa_assert(sample_size > 0); + +    b->nchannels = nchannels; +    b->sample_size = sample_size; +     +    if (!(b->data = sa_new0(void *, nchannels))) { +        b->size = NULL; +        return SA_ERROR_OOM; +    } + +    if (!(b->size = sa_new0(size_t, nchannels))) { +        sa_free(b->data); +        b->data = NULL; +        return SA_ERROR_OOM; +    } +         +    return SA_SUCCESS; +} + +void sa_bbuffer_done(sa_bbuffer_t *b) { +    unsigned i; +    sa_assert(b); + +    if (b->data) { +        for (i = 0; i < b->nchannels; i++) +            sa_free(b->data[i]); +         +        sa_free(b->data); +    } + +    sa_free(b->size); + +    b->data = NULL; +    b->size = NULL; +} + +void* sa_bbuffer_get(sa_bbuffer_t *b, unsigned channel, size_t size, int interleave) { +    sa_assert(b); +    sa_assert(channel < b->nchannels); +    sa_assert(size > 0); + +    if (interleave) { +         +        if (!b->data[0] || size * b->nchannels > b->size[0]) { +            sa_free(b->data[0]); +            b->size[0] = size * b->nchannels; + +            if (!(b->data[0] = sa_malloc(b->size[0]))) +                return NULL; +        } + +        return (uint8_t*) b->data[0] + (b->sample_size * channel); +         +    } else { + +        if (!b->data[channel] || size > b->size[channel]) { + +            sa_free(b->data[channel]); +            b->size[channel] = size; + +            if (!(b->data[channel] = sa_malloc(size))) +                return NULL; +        } + +        return b->data[channel]; +    } +} diff --git a/src/bbuffer.h b/src/bbuffer.h new file mode 100644 index 0000000..6394a11 --- /dev/null +++ b/src/bbuffer.h @@ -0,0 +1,19 @@ +#ifndef foosydneybbufferhfoo +#define foosydneybbufferhfoo + +#include <sys/types.h> + +/* Simple bounce buffer management routines */ + +typedef struct sa_bbuffer { +    void **data; +    size_t *size; +    unsigned nchannels; +    size_t sample_size; +} sa_bbuffer_t; + +int sa_bbuffer_init(sa_bbuffer_t *b, unsigned nchannels, size_t sample_size); +void sa_bbuffer_done(sa_bbuffer_t *b); +void* sa_bbuffer_get(sa_bbuffer_t *b, unsigned channel, size_t size, int interleave); + +#endif diff --git a/src/bufferq.c b/src/bufferq.c new file mode 100644 index 0000000..1965dda --- /dev/null +++ b/src/bufferq.c @@ -0,0 +1,270 @@ +#include <string.h> + +#include "malloc.h" +#include "macro.h" +#include "bufferq.h" + +#define SA_BUFFERQ_ITEM_CONCAT_DATA(x) ((void*) (uint8_t*) (x) + SA_ALIGN(sizeof(sa_bufferq_item_t))) + +int sa_bufferq_init(sa_bufferq_t *q, unsigned nchannels, size_t sample_size) { +    sa_assert(q); +    sa_assert(sample_size > 0); +    sa_assert(nchannels > 0); + +    memset(q, 0, sizeof(*q)); +    q->sample_size = sample_size; +    q->nchannels = nchannels; + +    if (!(q->items = sa_new0(sa_bufferq_item_t*, nchannels))) +        return SA_ERROR_OOM; + +    if (!(q->last = sa_new0(sa_bufferq_item_t*, nchannels))) { +        sa_free(q->items); +        q->items = NULL; +        return SA_ERROR_OOM; +    } +     +    return SA_SUCCESS; +} + +void sa_bufferq_done(sa_bufferq_t *q) { +    unsigned u; +    sa_assert(q); + +    for (u = 0; u < q->nchannels; u++) { +        sa_bufferq_item_t *i; +         +        while ((i = q->items[u])) { +            SA_LLIST_REMOVE(sa_bufferq_item_t, bufferq, q->items[u], i); +            sa_free(i); +        } +    } + +    sa_free(q->items); +    sa_free(q->last); +} + +static sa_bufferq_item_t* bufferq_item_new(const void *d, int64_t idx, size_t size, sa_bufferq_item_type_t type) { +    sa_bufferq_item_t *i; +    sa_assert(size > 0); + +    if (type == SA_BUFFERQ_ITEM_STATIC) { +        if (!(i = sa_new(sa_bufferq_item_t, 1))) +            return NULL; +        i->data = (void*) d; +    } else if (type == SA_BUFFERQ_ITEM_CONCATENATED) { +        if (!(i = sa_malloc(SA_ALIGN(sizeof(sa_bufferq_item_t)) + size))) +            return NULL; +        i->data = SA_BUFFERQ_ITEM_CONCAT_DATA(i); +        memcpy(i->data, d, size); +    } else { +        sa_assert(type == SA_BUFFERQ_ITEM_DYNAMIC); + +        if (!(i = sa_new(sa_bufferq_item_t, 1))) +            return NULL; +         +        i->data = (void*) d; +    } + +    i->type = type; +    i->idx = idx; +    i->size = size; +    SA_LLIST_ITEM_INIT(sa_bufferq_item_t, bufferq, i); + +    return i; +} + +static sa_bufferq_item_t* bufferq_item_make_writable(sa_bufferq_item_t *i) { +    void *d; +    sa_assert(i); +     +    if (i->type == SA_BUFFERQ_ITEM_CONCATENATED || i->type == SA_BUFFERQ_ITEM_DYNAMIC) +        return i; + +    if (!(d = sa_memdup(i->data, i->size))) +        return NULL; + +    i->data = d; +    i->type = SA_BUFFERQ_ITEM_DYNAMIC; +    return i; +} + +static void bufferq_item_free(sa_bufferq_item_t *i) { +    sa_assert(i); +     +    if (i->type == SA_BUFFERQ_ITEM_DYNAMIC) +        sa_free(i->data); +    sa_free(i); +} + +int sa_bufferq_push(sa_bufferq_t *q, unsigned channel, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence, sa_bufferq_item_type_t type) { +    int64_t idx; +    sa_bufferq_item_t *i, *j, *n; +     +    sa_assert(q); + +    switch (whence) { +        case SA_SEEK_RELATIVE: +            idx = q->write_index + offset; +            break; +        case SA_SEEK_ABSOLUTE: +            idx = offset; +            break; +        case SA_SEEK_RELATIVE_END: +            idx = q->end_index + offset; +            break; +        case _SA_SEEK_MAX: +            sa_assert_not_reached(); +    } + +    if (q->read_index > idx && type != SA_BUFFERQ_ITEM_DYNAMIC) { +        int64_t l = q->read_index - idx; + +        if (l > nbytes) +            l = nbytes; +         +        idx += l; +        data += l; +        nbytes -= l; +         +    } + +    /* Allocate the new entry */ +    if (!(j = bufferq_item_new(data, idx, nbytes, type))) +        return SA_ERROR_OOM; + +    /* Find the position where we need to insert the new entry */ +    for (i = q->items[channel]; i && idx >= i->idx + i->size; i = i->bufferq_next) +        ; + +    /* Shorten the current entry if necessary */ +    if (i && idx > i->idx) { +        i->size = idx - i->idx; +        i = i->bufferq_next; +    } +     +    /* Insert the entry */ +    if (i) +        SA_LLIST_INSERT_BEFORE(sa_bufferq_item_t, bufferq, q->items[channel], i, j); +    else { +        if (q->last[channel]) +            SA_LLIST_INSERT_AFTER(sa_bufferq_item_t, bufferq, q->items[channel], q->last[channel], j); +        else +            SA_LLIST_PREPEND(sa_bufferq_item_t, bufferq, q->items[channel], j); + +        q->last[channel] = j; +    } +     +    /* Now kick all the entries that overlap entirely with our new entry */ +    for (i = j->bufferq_next; i && i->idx + i->size < j->idx + j->size ; i = n) { +        n = i->bufferq_next; +        SA_LLIST_REMOVE(sa_bufferq_item_t, bufferq, q->items[channel], i); +        bufferq_item_free(i); +    } +         +    q->write_index = idx + nbytes; + +    if (q->write_index > q->end_index) +        q->end_index = q->write_index; + +    return SA_SUCCESS; +} + +void sa_bufferq_get(sa_bufferq_t *q, void *i[], size_t *bytes) { +    int first = 1; +    unsigned u; +    sa_assert(q); + +    *bytes = 0; +     +    for (u = 0; u < q->nchannels; u++) { + +        if (q->items[u]) { + +            if (q->items[u]->idx > q->read_index) { +                int64_t l; +                i[u] = NULL; + +                l = q->items[u]->idx - q->read_index; + +                if (first) { +                    *bytes = l; +                    first = 0; +                } else +                    *bytes = l < *bytes ? l : *bytes; +            } else { +                int64_t l; + +                i[u] = (uint8_t*) q->items[u]->data + q->read_index - q->items[u]->idx; + +                l = q->items[u]->size - (q->read_index - q->items[u]->idx); +                 +                if (first) { +                    *bytes = l; +                    first = 0; +                } else +                    *bytes = l < *bytes ? l : *bytes; +            } +             +        } else +            i[u] = NULL; +    } +} + + +void sa_bufferq_drop(sa_bufferq_t *q, int64_t bytes) { +    unsigned u; +     +    sa_assert(q); + +    q->read_index += bytes; + +    for (u = 0; u < q->nchannels; u++) { +        sa_bufferq_item_t *i; +         +        i = q->items[u]; +         +        while (i && q->read_index >= i->idx + i->size) { +            sa_bufferq_item_t *n = i->bufferq_next; + +            SA_LLIST_REMOVE(sa_bufferq_item_t, bufferq, q->items[u], i); + +            bufferq_item_free(i); +            i = n; +        } + +        if (!i) +            q->last[u] = NULL; +    } +} + +int sa_bufferq_realloc(sa_bufferq_t *q) { +    unsigned u; +    int fail = 0; +    sa_assert(q); + +    for (u = 0; u < q->nchannels; u++) { +        sa_bufferq_item_t *i; + +        for (i = q->items[u]; i; i = i->bufferq_next) { + +            if (i->type != SA_BUFFERQ_ITEM_STATIC) +                continue; + +            if (!bufferq_item_make_writable(i)) { +                fail = 1; + +                /* Hmm, we couldn't allocate memory, but we can't +                 * return without doing anything, hence let's at least +                 * drop the reference to the statically allocated +                 * data */ +                 +                i->size = 0; +                i->data = SA_BUFFERQ_ITEM_CONCAT_DATA(i); +                i->type = SA_BUFFERQ_ITEM_CONCATENATED; +            } +        } +    } + +    return fail ? SA_ERROR_OOM : SA_SUCCESS; +} diff --git a/src/bufferq.h b/src/bufferq.h new file mode 100644 index 0000000..2d53a45 --- /dev/null +++ b/src/bufferq.h @@ -0,0 +1,42 @@ +#ifndef foosydneybufferqhfoo +#define foosydneybufferqhfoo + +#include <inttypes.h> + +#include "macro.h" +#include "llist.h" +#include "sydney.h" + +typedef enum sa_bufferq_item_type { +    SA_BUFFERQ_ITEM_CONCATENATED, +    SA_BUFFERQ_ITEM_DYNAMIC, +    SA_BUFFERQ_ITEM_STATIC +} sa_bufferq_item_type_t; + +typedef struct sa_bufferq_item { +    void *data; +    int64_t idx; +    size_t size; +    sa_bufferq_item_type_t type; +    SA_LLIST_ITEM(struct sa_bufferq_item, bufferq); +} sa_bufferq_item_t; + +typedef struct sa_bufferq { +    SA_LLIST_HEAD(sa_bufferq_item_t, *items); +    sa_bufferq_item_t **last; +    int64_t read_index, write_index, end_index; +    size_t sample_size; +    unsigned nchannels; +} sa_bufferq_t; + +int sa_bufferq_init(sa_bufferq_t *q, unsigned nchannels, size_t sample_size); + +void sa_bufferq_done(sa_bufferq_t *q); + +int sa_bufferq_push(sa_bufferq_t *q, unsigned channel, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence, sa_bufferq_item_type_t type); +int sa_bufferq_realloc(sa_bufferq_t *q); + +void sa_bufferq_get(sa_bufferq_t *q, void *i[], size_t *bytes); +void sa_bufferq_drop(sa_bufferq_t *q, int64_t bytes); + +#endif diff --git a/src/byteswap.c b/src/byteswap.c new file mode 100644 index 0000000..8ae0b7a --- /dev/null +++ b/src/byteswap.c @@ -0,0 +1,57 @@ +#include <inttypes.h> + +#include "macro.h" +#include "byteswap.h" + +static void byteswap16(void *_dst, size_t dstr, const void *_src, size_t sstr, size_t bytes) { +    uint16_t *dst = _dst; +    const uint16_t *src = _src; +    unsigned n = bytes / sizeof(uint16_t); + +    for (; n > 0; n--) { +        *dst = (*src >> 8) | (*src << 8); +        src += sstr / sizeof(uint16_t); +        dst += dstr / sizeof(uint16_t); +    } +} + +static void byteswap24(void *_dst, size_t dstr, const void *_src, size_t sstr, size_t bytes) { +    uint8_t *dst = _dst; +    const uint8_t *src = _src; +    unsigned n = bytes / (sizeof(uint8_t)*3); +     +    for (; n > 0; n--) { +        dst[0] = src[2]; +        dst[2] = src[0]; +         +        src += sstr / (sizeof(uint8_t)*3); +        dst += dstr / (sizeof(uint8_t)*3); +    } +} + +static void byteswap32(void *_dst, size_t dstr, const void *_src, size_t sstr, size_t bytes) { +    uint32_t *dst = _dst; +    const uint32_t *src = _src; +    unsigned n = bytes / sizeof(uint32_t); +     +    for (; n > 0; n--) { +        *dst = (*src << 24) | ((*src & 0xFF00) << 8) | ((*src >> 8) & 0xFF00) | (*src >> 24); +        src += sstr / sizeof(uint32_t); +        dst += dstr / sizeof(uint32_t); +    } +} + +sa_byteswap_func_t sa_get_byteswap_func(sa_pcm_format_t f) { +     +    static const sa_byteswap_func_t funcs[_SA_PCM_FORMAT_MAX] = { +        [SA_PCM_FORMAT_S16_RE] = byteswap16, +        [SA_PCM_FORMAT_S24_RE] = byteswap24, +        [SA_PCM_FORMAT_S32_RE] = byteswap32, +        [SA_PCM_FORMAT_FLOAT32_BE] = byteswap32, +    }; + +    sa_assert(f < _SA_PCM_FORMAT_MAX);  + +    return funcs[f]; +} + diff --git a/src/byteswap.h b/src/byteswap.h new file mode 100644 index 0000000..4116677 --- /dev/null +++ b/src/byteswap.h @@ -0,0 +1,12 @@ +#ifndef foosydneyhbyteswaphfoo +#define foosydneyhbyteswaphfoo + +#include <sys/types.h> + +#include "sydney.h" + +typedef void (*sa_byteswap_func_t) (void *dst, size_t dstr, const void *src, size_t sstr, size_t bytes); + +sa_byteswap_func_t sa_get_byteswap_func(sa_pcm_format_t f); + +#endif diff --git a/src/common.c b/src/common.c new file mode 100644 index 0000000..5a81d02 --- /dev/null +++ b/src/common.c @@ -0,0 +1,1266 @@ +#include <string.h> +#include <errno.h> +#include <liboil/liboil.h> + +#include "sydney.h" +#include "macro.h" +#include "malloc.h" +#include "common.h" +#include "driver.h" +#include "mutex.h" + +/* contains code */ +#include "meta-name-table.h" + +static sa_stream_t *stream_alloc(void) { +    sa_stream_t *d; + +    if (!(d = sa_new0(sa_stream_t, 1))) +        return NULL; + +    /* All fields a carefully chosen in a way that initializing them +     * NUL bytes is sufficient */ + +    if (!(d->mutex = sa_mutex_new(0))) { +        sa_free(d); +        return NULL; +    } +     +    return d; +} + +int sa_stream_create_opaque( +        sa_stream_t **s, +        const char *client_name, +        sa_mode_t mode, +        const char *codec) { +     +    int error; + +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(mode == SA_MODE_RDONLY || mode == SA_MODE_WRONLY || mode == SA_MODE_RDWR, SA_ERROR_INVALID); +    sa_return_val_if_fail(codec, SA_ERROR_INVALID); + +    if (!(*s = stream_alloc())) +        return SA_ERROR_OOM; + +    (*s)->mode = mode; + +    if (!((*s)->codec = sa_strdup(codec))) { +        error = SA_ERROR_OOM; +        goto fail; +    } + +    oil_init(); + +    if (client_name) +        if ((error = sa_stream_change_meta_data(*s, SA_META_CLIENT_NAME, client_name, strlen(client_name)+1)) < 0) +            goto fail; + +    return SA_SUCCESS; + +fail: +    sa_stream_destroy(*s); +    return error; +} + +int sa_stream_create_pcm( +        sa_stream_t **s, +        const char *client_name, +        sa_mode_t mode, +        sa_pcm_format_t format, +        unsigned rate, +        unsigned nchannels) { + +    int ret; +    size_t lwm; +     +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(mode == SA_MODE_RDONLY || mode == SA_MODE_WRONLY || mode == SA_MODE_RDWR, SA_ERROR_INVALID); +    sa_return_val_if_fail(format < _SA_PCM_FORMAT_MAX, SA_ERROR_INVALID); +    sa_return_val_if_fail(rate > 0, SA_ERROR_INVALID); +    sa_return_val_if_fail(nchannels > 0, SA_ERROR_INVALID); + +    if (!(*s = stream_alloc())) +        return SA_ERROR_OOM; + +    (*s)->mode = mode; +    (*s)->pcm_attrs.format = format; +    (*s)->pcm_attrs.nchannels = nchannels; +    (*s)->pcm_sample_size = sa_get_pcm_sample_size(format); +    (*s)->pcm_frame_size = (*s)->pcm_sample_size * nchannels; + +    if (nchannels <= 2) { +        static const sa_channel_t map_stereo[2] = { SA_CHANNEL_LEFT, SA_CHANNEL_RIGHT }; +        static const sa_channel_t map_mono[1] = { SA_CHANNEL_MONO }; + +        if ((ret = sa_stream_set_channel_map(*s, nchannels == 2 ? map_stereo : map_mono, nchannels))) +            goto fail; +    } + +    if ((ret = sa_stream_change_rate(*s, rate))) +        goto fail; +     +    lwm = ((*s)->pcm_frame_size * (*s)->pcm_attrs.rate) / 20; /* 50 ms */ + +    if (lwm <= 0) +        lwm = (*s)->pcm_frame_size * (*s)->pcm_attrs.rate; /* 1s */ +             +    if (mode & SA_MODE_RDONLY) { + +        if ((ret = sa_stream_set_read_lower_watermark(*s, lwm))) +            goto fail; + +        if ((ret = sa_stream_set_read_upper_watermark(*s, lwm*2))) +            goto fail; +    }  + +    if (mode & SA_MODE_WRONLY) { + +        if ((ret = sa_stream_set_write_lower_watermark(*s, lwm))) +            goto fail; + +        if ((ret = sa_stream_set_write_upper_watermark(*s, lwm*2))) +            goto fail; +    } +     +    oil_init(); + +    if (client_name) +        if ((ret = sa_stream_change_meta_data(*s, SA_META_CLIENT_NAME, client_name, strlen(client_name))) < 0) +            goto fail; +     +    return SA_SUCCESS; + +fail: +     +    sa_stream_destroy(*s); +    return ret; +} + +int sa_stream_open(sa_stream_t *s) { +    int ret; +     +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_INIT, SA_ERROR_STATE); +    sa_return_val_if_fail_mutex(s->mutex, s->codec || s->pcm_attrs.channel_map, SA_ERROR_NO_INIT); +    sa_return_val_if_fail_mutex(s->mutex, !(s->mode & SA_MODE_RDONLY) || (s->read_lower_watermark <= s->read_upper_watermark), SA_ERROR_INVALID); +    sa_return_val_if_fail_mutex(s->mutex, !(s->mode & SA_MODE_WRONLY) || (s->write_lower_watermark <= s->write_upper_watermark), SA_ERROR_INVALID); +    sa_return_val_if_fail_mutex(s->mutex, !(s->mode & SA_MODE_RDONLY) || !s->codec || (s->read_lower_watermark > 0 && s->read_upper_watermark > 0), SA_ERROR_NO_INIT); +    sa_return_val_if_fail_mutex(s->mutex, !(s->mode & SA_MODE_WRONLY) || !s->codec || (s->write_lower_watermark > 0 && s->write_upper_watermark > 0), SA_ERROR_NO_INIT); + +    if ((ret = driver_open(s)) == 0) +        s->state = SA_STATE_STOPPED; + +    sa_mutex_unlock(s->mutex); + +    return ret; +} + +int sa_stream_destroy(sa_stream_t *s) { +    int ret; +    unsigned u; +     +    sa_return_val_if_fail_mutex(s->mutex, s, SA_ERROR_INVALID); + +    ret = driver_destroy(s); + +    sa_free(s->codec); +    sa_free(s->driver); +    sa_free(s->device); +    sa_free(s->pcm_attrs.channel_map); +    sa_free(s->read_volume); +    sa_free(s->write_volume); + +    for (u = 0; u < _META_NAMES_MAX; u++) +        sa_free(s->meta_data[u]); + +    sa_mutex_free(s->mutex); +    sa_free(s); +    return ret; +} + +int sa_stream_set_write_lower_watermark(sa_stream_t *s, size_t size) { + +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(size > 0, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_INIT, SA_ERROR_STATE); +    sa_return_val_if_fail_mutex(s->mutex, s->mode & SA_MODE_WRONLY, SA_ERROR_STATE); + +    s->write_lower_watermark = size; + +    sa_mutex_unlock(s->mutex); + +    return SA_SUCCESS; +} + +int sa_stream_set_read_lower_watermark(sa_stream_t *s, size_t size) { + +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(size > 0, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_INIT, SA_ERROR_STATE); +    sa_return_val_if_fail_mutex(s->mutex, s->mode & SA_MODE_RDONLY, SA_ERROR_STATE); + +    s->read_lower_watermark = size; + +    sa_mutex_unlock(s->mutex); +    return SA_SUCCESS; +} + +int sa_stream_set_write_upper_watermark(sa_stream_t *s, size_t size) { + +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(size > 0, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_INIT, SA_ERROR_STATE); +    sa_return_val_if_fail_mutex(s->mutex, s->mode & SA_MODE_WRONLY, SA_ERROR_STATE); + +    s->write_upper_watermark = size; + +    sa_mutex_unlock(s->mutex); +    return SA_SUCCESS; +} + +int sa_stream_set_read_upper_watermark(sa_stream_t *s, size_t size) { + +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(size > 0, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_INIT, SA_ERROR_STATE); +    sa_return_val_if_fail_mutex(s->mutex, s->mode & SA_MODE_RDONLY, SA_ERROR_STATE); + +    s->read_upper_watermark = size; + +    sa_mutex_unlock(s->mutex); +    return SA_SUCCESS; +} + +int sa_stream_set_channel_map(sa_stream_t *s, const sa_channel_t *map, unsigned n) { +    const sa_channel_t *c; +    sa_channel_t *m; +     +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(map, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_INIT, SA_ERROR_STATE); +    sa_return_val_if_fail_mutex(s->mutex, !s->codec, SA_ERROR_STATE); +    sa_return_val_if_fail_mutex(s->mutex, n == s->pcm_attrs.nchannels, SA_ERROR_INVALID); + +    for (c = map; n > 0; c++, n--) +        if (*c >= _SA_CHANNEL_MAX) { +            sa_mutex_unlock(s->mutex); +            return SA_ERROR_INVALID; +        } +     +    if (!(m = sa_memdup(map, sizeof(sa_channel_t) * s->pcm_attrs.nchannels))) { +        sa_mutex_unlock(s->mutex); +        return SA_ERROR_OOM; +    } + +    sa_free(s->pcm_attrs.channel_map); +    s->pcm_attrs.channel_map = m; + +    sa_mutex_unlock(s->mutex); +    return SA_SUCCESS; +} + +int sa_stream_set_xrun_mode(sa_stream_t *s, sa_xrun_mode_t mode) { +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(mode == SA_XRUN_MODE_STOP || mode == SA_XRUN_MODE_SPIN, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_INIT, SA_ERROR_STATE); + +    s->xrun_mode = mode; + +    sa_mutex_unlock(s->mutex); +    return SA_SUCCESS; +} + +int sa_stream_set_non_interleaved(sa_stream_t *s, int enable) { +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_INIT, SA_ERROR_INVALID); +    sa_return_val_if_fail_mutex(s->mutex, !s->codec, SA_ERROR_STATE); + +    s->ni_enabled = !!enable; + +    sa_mutex_unlock(s->mutex); +    return SA_SUCCESS; +} + +int sa_stream_set_dynamic_rate(sa_stream_t *s, int enable) { +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_INIT, SA_ERROR_INVALID); +    sa_return_val_if_fail_mutex(s->mutex, !s->codec, SA_ERROR_STATE); + +    s->dynamic_rate_enabled = !!enable; + +    sa_mutex_unlock(s->mutex); +    return SA_SUCCESS; +} + +int sa_stream_set_driver(sa_stream_t *s, const char *driver) { +    char *d; +     +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(driver, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_INIT, SA_ERROR_STATE); + +    if (!(d = sa_strdup(driver))) { +        sa_mutex_unlock(s->mutex); +        return SA_ERROR_OOM; +    } +     +    sa_free(s->driver); +    s->driver = d; +     +    sa_mutex_unlock(s->mutex); +    return SA_SUCCESS; +} + +int sa_stream_start_thread(sa_stream_t *s, sa_event_callback_t callback) { +    int r; +     +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(callback, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_RUNNING || s->state == SA_STATE_STOPPED, SA_ERROR_STATE); +    sa_return_val_if_fail_mutex(s->mutex, !s->callback, SA_ERROR_STATE); + +    r = driver_start_thread(s, callback); + +    if (r == SA_SUCCESS) +        s->callback = callback; +     +    sa_mutex_unlock(s->mutex); +    return r; +} + +int sa_stream_stop_thread(sa_stream_t *s) { +    int r; +     +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_RUNNING || s->state == SA_STATE_STOPPED, SA_ERROR_STATE); +    sa_return_val_if_fail_mutex(s->mutex, s->callback, SA_ERROR_STATE); + +    r = driver_stop_thread(s); + +    if (r == SA_SUCCESS) +        s->callback = NULL; +     +    sa_mutex_unlock(s->mutex); +    return r; +} + +int sa_stream_change_device(sa_stream_t *s, const char *device_name) { +    char *d; +    int ret; +     +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(device_name, SA_ERROR_INVALID); + +    if (!(d = sa_strdup(device_name))) +        return SA_ERROR_OOM; + +    sa_mutex_lock(s->mutex); + +    ret = s->state == SA_STATE_INIT ? SA_SUCCESS : driver_change_device(s, device_name); + +    if (ret == SA_SUCCESS) { +        sa_free(s->device); +        s->device = d; +    } else +        sa_free(d); + +    sa_mutex_unlock(s->mutex); +     +    return ret; +} + +int sa_stream_change_read_volume(sa_stream_t *s, const int32_t vol[], unsigned n) { +    int *v, ret; + +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(vol, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, s->mode & SA_MODE_RDONLY, SA_ERROR_STATE); +    sa_return_val_if_fail_mutex(s->mutex, (!s->codec && n == s->pcm_attrs.nchannels) || s->pcm_attrs.nchannels == 1, SA_ERROR_INVALID); + +    if (s->codec || s->pcm_attrs.nchannels == n) { +        if (!(v = sa_newdup(int32_t, vol, n))) { +            sa_mutex_unlock(s->mutex); +            return SA_ERROR_OOM; +        } +    } else { +        unsigned i; + +        if (!(v = sa_new(int32_t, s->pcm_attrs.nchannels))) { +            sa_mutex_unlock(s->mutex); +            return SA_ERROR_OOM; +        } +         +        for (i = 0; i < s->pcm_attrs.nchannels; i++) +            v[i] = vol[0]; +    } +     +    ret = s->state == SA_STATE_INIT ? SA_SUCCESS : driver_change_read_volume(s, v); + +    if (ret == SA_SUCCESS) { +        sa_free(s->read_volume); +        s->read_volume = v; +    } else +        sa_free(v); + +    sa_mutex_unlock(s->mutex); +    return ret; +} + +int sa_stream_change_write_volume(sa_stream_t *s, const int32_t vol[], unsigned n) { +    int *v, ret; + +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(vol, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, s->mode & SA_MODE_WRONLY, SA_ERROR_STATE); +    sa_return_val_if_fail_mutex(s->mutex, (!s->codec && n == s->pcm_attrs.nchannels) || s->pcm_attrs.nchannels == 1, SA_ERROR_INVALID); + +    if (s->codec || s->pcm_attrs.nchannels == n) { +        if (!(v = sa_newdup(int32_t, vol, n))) { +            sa_mutex_unlock(s->mutex); +            return SA_ERROR_OOM; +        } +    } else { +        unsigned i; + +        if (!(v = sa_new(int32_t, s->pcm_attrs.nchannels))) { +            sa_mutex_unlock(s->mutex); +            return SA_ERROR_OOM; +        } +         +        for (i = 0; i < s->pcm_attrs.nchannels; i++) +            v[i] = vol[0]; +    } + +    ret = s->state == SA_STATE_INIT ? SA_SUCCESS : driver_change_write_volume(s, v); + +    if (ret == SA_SUCCESS) { +        sa_free(s->write_volume); +        s->write_volume = v; +    } else +        sa_free(v); + +    sa_mutex_unlock(s->mutex); +    return ret; +} + +int sa_stream_change_rate(sa_stream_t *s, unsigned rate) { +    int ret; +     +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(rate > 0, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, !s->codec, SA_ERROR_STATE); +    sa_return_val_if_fail_mutex(s->mutex, s->dynamic_rate_enabled || s->state == SA_STATE_INIT, SA_ERROR_STATE); + +    ret = s->state == SA_STATE_INIT ? SA_SUCCESS : driver_change_rate(s, rate); + +    if (ret == SA_SUCCESS) +        s->pcm_attrs.rate = rate; + +    sa_mutex_unlock(s->mutex); +    return ret; +} + +int sa_stream_change_user_data(sa_stream_t *s, const void *value) { +    sa_return_val_if_fail(s->mutex, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +     +    s->user_data = (void*) value; +     +    sa_mutex_unlock(s->mutex); +    return SA_SUCCESS; +} + +int sa_stream_set_adjust_rate(sa_stream_t *s, sa_adjust_t direction) { +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, !s->codec, SA_ERROR_STATE); +    sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_INIT, SA_ERROR_STATE); + +    s->adjust_rate = direction; + +    sa_mutex_unlock(s->mutex); +    return SA_SUCCESS; +} + +int sa_stream_set_adjust_nchannels(sa_stream_t *s, sa_adjust_t direction) { +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, !s->codec, SA_ERROR_STATE); +    sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_INIT, SA_ERROR_STATE); + +    s->adjust_rate = direction; + +    sa_mutex_unlock(s->mutex); +    return SA_SUCCESS; +} + +int sa_stream_set_adjust_pcm_format(sa_stream_t *s, sa_adjust_t direction) { +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, !s->codec, SA_ERROR_STATE); +    sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_INIT, SA_ERROR_STATE); + +    s->adjust_pcm_format = direction; + +    sa_mutex_unlock(s->mutex); +    return SA_SUCCESS; +} + +int sa_stream_set_adjust_watermarks(sa_stream_t *s, sa_adjust_t direction) { +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_INIT, SA_ERROR_STATE); + +    s->adjust_watermarks = direction; + +    sa_mutex_unlock(s->mutex); +    return SA_SUCCESS; +} + +int sa_stream_get_state(sa_stream_t *s, sa_state_t *state) { +    int ret; +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, state, SA_ERROR_INVALID); + +    if (s->state == SA_STATE_INIT) { +        *state = s->state; +        ret = SA_SUCCESS; +    } else +        ret = driver_get_state(s, state); + +    sa_mutex_unlock(s->mutex); +    return ret; +} + +int sa_stream_get_rate(sa_stream_t *s, unsigned *rate) { +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(rate, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, !s->codec, SA_ERROR_STATE); + +    *rate = s->pcm_attrs.rate; + +    sa_mutex_unlock(s->mutex); +    return SA_SUCCESS; +} + +int sa_stream_get_nchannels(sa_stream_t *s, int *nchannels) { +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(nchannels, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, !s->codec, SA_ERROR_STATE); + +    *nchannels = s->pcm_attrs.nchannels; + +    sa_mutex_unlock(s->mutex); +    return SA_SUCCESS; +} + +int sa_stream_get_pcm_format(sa_stream_t *s, sa_pcm_format_t *pcm_format) { +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(pcm_format, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, !s->codec, SA_ERROR_STATE); + +    *pcm_format = s->pcm_attrs.format; +    sa_mutex_unlock(s->mutex); +    return SA_SUCCESS; +} + +int sa_stream_get_mode(sa_stream_t *s, sa_mode_t *access_mode) { +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(access_mode, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); + +    *access_mode = s->mode; +    sa_mutex_unlock(s->mutex); +    return SA_SUCCESS; +} + +int sa_stream_get_codec(sa_stream_t *s, char *codec, size_t *size) { +    size_t n; +     +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(size && (*size == 0 || codec), SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, s->codec, SA_ERROR_STATE); + +    n = strlen(s->codec)+1; +    if (*size < n) { +        sa_mutex_unlock(s->mutex); +        return SA_ERROR_NO_SPACE; +    } + +    if (codec) +        strcpy(codec, s->codec); +    *size = n; +                 +    sa_mutex_unlock(s->mutex); +    return SA_SUCCESS; +} + +int sa_stream_get_write_lower_watermark(sa_stream_t *s, size_t *size) { +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(size, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, s->mode & SA_MODE_WRONLY, SA_ERROR_STATE); + +    *size = s->write_lower_watermark; + +    sa_mutex_unlock(s->mutex); +    return SA_SUCCESS; +} + +int sa_stream_get_read_lower_watermark(sa_stream_t *s, size_t *size) { +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(size, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, s->mode & SA_MODE_RDONLY, SA_ERROR_STATE); + +    *size = s->read_lower_watermark; + +    sa_mutex_unlock(s->mutex); +    return SA_SUCCESS; +} + +int sa_stream_get_write_upper_watermark(sa_stream_t *s, size_t *size) { +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(size, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, s->mode & SA_MODE_WRONLY, SA_ERROR_STATE); + +    *size = s->write_upper_watermark; + +    sa_mutex_unlock(s->mutex); +    return SA_SUCCESS; +} + +int sa_stream_get_read_upper_watermark(sa_stream_t *s, size_t *size) { +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(size, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, s->mode & SA_MODE_RDONLY, SA_ERROR_STATE); + +    *size = s->read_upper_watermark; + +    sa_mutex_unlock(s->mutex); +    return SA_SUCCESS; +} + +int sa_stream_get_channel_map(sa_stream_t *s, sa_channel_t *map, unsigned *n) { +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(n && (*n == 0 || map), SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, !s->codec, SA_ERROR_STATE); + +    if (*n < s->pcm_attrs.nchannels) { +        sa_mutex_unlock(s->mutex); +        return SA_ERROR_NO_SPACE; +    } + +    if (map) +        memcpy(map, s->pcm_attrs.channel_map, s->pcm_attrs.nchannels * sizeof(sa_channel_t)); +    *n = s->pcm_attrs.nchannels; + +    sa_mutex_unlock(s->mutex); +    return SA_SUCCESS; +} + +int sa_stream_get_xrun_mode(sa_stream_t *s, sa_xrun_mode_t *mode) { +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(mode, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); + +    *mode = s->xrun_mode; + +    sa_mutex_unlock(s->mutex); +    return SA_SUCCESS; +} + +int sa_stream_get_non_interleaved(sa_stream_t *s, int *enabled) { +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(enabled, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); + +    *enabled = s->ni_enabled; + +    sa_mutex_unlock(s->mutex); +    return SA_SUCCESS; +} + +int sa_stream_get_dynamic_rate(sa_stream_t *s, int *enabled) { +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(enabled, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); + +    *enabled = s->dynamic_rate_enabled; + +    sa_mutex_unlock(s->mutex); +    return SA_SUCCESS; +} + +int sa_stream_get_driver(sa_stream_t *s, char *driver, size_t *size) { +    size_t n; +     +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(size && (*size == 0 || driver), SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, s->driver, SA_ERROR_STATE); + +    n = strlen(s->driver)+1; +    if (*size < n) { +        sa_mutex_unlock(s->mutex); +        return SA_ERROR_NO_SPACE; +    } + +    if (driver) +        strcpy(driver, s->driver); +    *size = n; +                 +    sa_mutex_unlock(s->mutex); +    return SA_SUCCESS; +} + +int sa_stream_get_device(sa_stream_t *s, char *device, size_t *size) { +    size_t n; + +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(size && (*size == 0 || device), SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, s->device, SA_ERROR_STATE); + +    n = strlen(s->device)+1; +    if (*size < n) { +        sa_mutex_unlock(s->mutex); +        return SA_ERROR_NO_SPACE; +    } + +    if (device) +        strcpy(device, s->device); +    *size = n; + +    sa_mutex_unlock(s->mutex); +    return SA_SUCCESS; +} + +int sa_stream_get_read_volume(sa_stream_t *s, int32_t vol[], unsigned *n) { +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(n && (*n == 0 || vol), SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, s->mode & SA_MODE_RDONLY, SA_ERROR_STATE); +    sa_return_val_if_fail_mutex(s->mutex, s->read_volume, SA_ERROR_STATE); + +    if (*n < s->pcm_attrs.nchannels) { +        sa_mutex_unlock(s->mutex); +        return SA_ERROR_NO_SPACE; +    } + +    if (vol) +        memcpy(vol, s->read_volume, s->pcm_attrs.nchannels * sizeof(int32_t)); +    *n = s->pcm_attrs.nchannels; + +    sa_mutex_unlock(s->mutex); +    return SA_SUCCESS; +} + +int sa_stream_get_write_volume(sa_stream_t *s, int32_t vol[], unsigned *n) { +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(n && (*n == 0 || vol), SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, s->mode & SA_MODE_WRONLY, SA_ERROR_STATE); +    sa_return_val_if_fail_mutex(s->mutex, s->write_volume, SA_ERROR_STATE); + +    if (*n < s->pcm_attrs.nchannels) { +        sa_mutex_unlock(s->mutex); +        return SA_ERROR_NO_SPACE; +    } + +    if (vol) +        memcpy(vol, s->write_volume, s->pcm_attrs.nchannels * sizeof(int32_t)); +    *n = s->pcm_attrs.nchannels; + +    sa_mutex_unlock(s->mutex); +    return SA_SUCCESS; +} + +int sa_stream_get_adjust_rate(sa_stream_t *s, sa_adjust_t *direction) { +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(direction, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, !s->codec, SA_ERROR_STATE); + +    *direction = s->adjust_rate; + +    sa_mutex_unlock(s->mutex); +    return SA_SUCCESS; +} + +int sa_stream_get_adjust_nchannels(sa_stream_t *s, sa_adjust_t *direction) { +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(direction, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, !s->codec, SA_ERROR_STATE); + +    *direction = s->adjust_nchannels; + +    sa_mutex_unlock(s->mutex); +    return SA_SUCCESS; +} + +int sa_stream_get_adjust_pcm_format(sa_stream_t *s, sa_adjust_t *direction) { +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(direction, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, !s->codec, SA_ERROR_STATE); + +    *direction = s->adjust_pcm_format; + +    sa_mutex_unlock(s->mutex); +    return SA_SUCCESS; +} + +int sa_stream_get_adjust_watermarks(sa_stream_t *s, sa_adjust_t *direction) { +    sa_return_val_if_fail_mutex(s->mutex, s, SA_ERROR_INVALID); +    sa_return_val_if_fail_mutex(s->mutex, direction, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); + +    *direction = s->adjust_watermarks; + +    sa_mutex_unlock(s->mutex); +    return SA_SUCCESS; +} + +int sa_stream_get_user_data(sa_stream_t *s, void **value) { +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(value, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); + +    *value = s->user_data; + +    sa_mutex_unlock(s->mutex); +    return SA_SUCCESS; +} + +int sa_stream_get_event_error(sa_stream_t *s, sa_error_t *error) { +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(error, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, s->event == SA_EVENT_ERROR, SA_ERROR_STATE); + +    *error = s->error; + +    sa_mutex_unlock(s->mutex); +    return SA_SUCCESS; +} + +int sa_stream_get_event_notify(sa_stream_t *s, sa_notify_t *notify) { +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(notify, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, s->event == SA_EVENT_NOTIFY, SA_ERROR_STATE); + +    *notify = s->notify; + +    sa_mutex_unlock(s->mutex); +    return SA_SUCCESS; +} + +int sa_stream_get_position(sa_stream_t *s, sa_position_t position, int64_t *pos) { +    int ret; +     +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(pos, SA_ERROR_INVALID); +    sa_return_val_if_fail(position < _SA_POSITION_MAX, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_RUNNING || s->state == SA_STATE_STOPPED, SA_ERROR_STATE); + +    ret = driver_get_position(s, position, pos); + +    sa_mutex_unlock(s->mutex); +    return ret; +} + +int sa_stream_read(sa_stream_t *s, void *data, size_t nbytes) { +    int ret; +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(data, SA_ERROR_INVALID); +    sa_return_val_if_fail(nbytes > 0, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, !s->ni_enabled, SA_ERROR_STATE); +    sa_return_val_if_fail_mutex(s->mutex, s->codec || (nbytes % s->pcm_frame_size) == 0, SA_ERROR_INVALID); +    sa_return_val_if_fail_mutex(s->mutex, s->mode & SA_MODE_RDONLY, SA_ERROR_STATE); +    sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_RUNNING || s->state == SA_STATE_STOPPED, SA_ERROR_STATE); + +    ret = driver_read(s, data, nbytes); + +    sa_mutex_unlock(s->mutex); +    return ret; +} + +int sa_stream_read_ni(sa_stream_t *s, unsigned channel, void *data, size_t nbytes) { +    int ret; + +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(data, SA_ERROR_INVALID); +    sa_return_val_if_fail(nbytes > 0, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, !s->codec, SA_ERROR_STATE); +    sa_return_val_if_fail_mutex(s->mutex, channel < s->pcm_attrs.nchannels, SA_ERROR_INVALID); +    sa_return_val_if_fail_mutex(s->mutex, s->ni_enabled, SA_ERROR_STATE); +    sa_return_val_if_fail_mutex(s->mutex, (nbytes % s->pcm_sample_size) == 0, SA_ERROR_INVALID); +    sa_return_val_if_fail_mutex(s->mutex, s->mode & SA_MODE_RDONLY, SA_ERROR_STATE); +    sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_RUNNING || s->state == SA_STATE_STOPPED, SA_ERROR_STATE); + +    ret = driver_read_ni(s, channel, data, nbytes); +     +    sa_mutex_unlock(s->mutex); +    return ret; +} + +int sa_stream_write(sa_stream_t *s, const void *data, size_t nbytes) { +    return sa_stream_pwrite(s, data, nbytes, 0, SA_SEEK_RELATIVE); +} + +int sa_stream_write_ni(sa_stream_t *s, unsigned channel, const void *data, size_t nbytes) { +    return sa_stream_pwrite_ni(s, channel, data, nbytes, 0, SA_SEEK_RELATIVE); +} + +int sa_stream_pwrite(sa_stream_t *s, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence) { +    int ret; +     +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(data, SA_ERROR_INVALID); +    sa_return_val_if_fail(nbytes > 0, SA_ERROR_INVALID); +    sa_return_val_if_fail(whence == SA_SEEK_RELATIVE || whence == SA_SEEK_ABSOLUTE || whence == SA_SEEK_RELATIVE_END, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, !s->ni_enabled, SA_ERROR_STATE); +    sa_return_val_if_fail_mutex(s->mutex, s->codec || (nbytes % s->pcm_frame_size) == 0, SA_ERROR_INVALID); +    sa_return_val_if_fail_mutex(s->mutex, s->codec || (offset % s->pcm_frame_size) == 0, SA_ERROR_INVALID); +    sa_return_val_if_fail_mutex(s->mutex, s->mode & SA_MODE_WRONLY, SA_ERROR_STATE); +    sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_RUNNING || s->state == SA_STATE_STOPPED, SA_ERROR_STATE); + +    ret = driver_pwrite(s, data, nbytes, offset, whence); + +    sa_mutex_unlock(s->mutex); +    return ret; +} + +int sa_stream_pwrite_ni(sa_stream_t *s, unsigned channel, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence) { +    int ret; + +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(data, SA_ERROR_INVALID); +    sa_return_val_if_fail(nbytes > 0, SA_ERROR_INVALID); +    sa_return_val_if_fail(whence == SA_SEEK_RELATIVE || whence == SA_SEEK_ABSOLUTE || whence == SA_SEEK_RELATIVE_END, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, !s->codec, SA_ERROR_STATE); +    sa_return_val_if_fail_mutex(s->mutex, channel < s->pcm_attrs.nchannels, SA_ERROR_INVALID); +    sa_return_val_if_fail_mutex(s->mutex, s->ni_enabled, SA_ERROR_STATE); +    sa_return_val_if_fail_mutex(s->mutex, (nbytes % s->pcm_sample_size) == 0, SA_ERROR_INVALID); +    sa_return_val_if_fail_mutex(s->mutex, (offset % s->pcm_sample_size) == 0, SA_ERROR_INVALID); +    sa_return_val_if_fail_mutex(s->mutex, s->mode & SA_MODE_WRONLY, SA_ERROR_STATE); +    sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_RUNNING || s->state == SA_STATE_STOPPED, SA_ERROR_STATE); + +    ret = driver_pwrite_ni(s, channel, data, nbytes, offset, whence); + +    sa_mutex_unlock(s->mutex); +    return ret; +} + +int sa_stream_get_read_size(sa_stream_t *s, size_t *size) { +    int ret; + +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(size, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, s->mode & SA_MODE_RDONLY, SA_ERROR_STATE); +    sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_RUNNING || s->state == SA_STATE_STOPPED, SA_ERROR_STATE); + +    ret = driver_get_read_size(s, size); + +    sa_mutex_unlock(s->mutex); +    return ret; +} + +int sa_stream_get_write_size(sa_stream_t *s, size_t *size) { +    int ret; +     +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(size, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, s->mode & SA_MODE_WRONLY, SA_ERROR_STATE); +    sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_RUNNING || s->state == SA_STATE_STOPPED, SA_ERROR_STATE); + +    ret = driver_get_write_size(s, size); + +    sa_mutex_unlock(s->mutex); +    return ret; +} + +int sa_stream_resume(sa_stream_t *s) { +    int ret; +     +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_RUNNING || s->state == SA_STATE_STOPPED, SA_ERROR_STATE); + +    ret = driver_resume(s); + +    sa_mutex_unlock(s->mutex); +    return ret; +} + +int sa_stream_pause(sa_stream_t *s) { +    int ret; + +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_RUNNING || s->state == SA_STATE_STOPPED, SA_ERROR_STATE); + +    ret = driver_pause(s); + +    sa_mutex_unlock(s->mutex); +    return ret; +} + +int sa_stream_drain(sa_stream_t *s) { +    int ret; +     +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, s->mode & SA_MODE_WRONLY, SA_ERROR_STATE); +    sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_RUNNING || s->state == SA_STATE_STOPPED, SA_ERROR_STATE); + +    ret = driver_drain(s); + +    sa_mutex_unlock(s->mutex); +    return ret; +} + +size_t sa_get_pcm_sample_size(sa_pcm_format_t f) { +     +    switch (f) { +        case SA_PCM_FORMAT_U8: +        case SA_PCM_FORMAT_ULAW: +        case SA_PCM_FORMAT_ALAW: +            return 1; + +        case SA_PCM_FORMAT_S16_LE: +        case SA_PCM_FORMAT_S16_BE: +            return 2; +        case SA_PCM_FORMAT_S24_LE: +        case SA_PCM_FORMAT_S24_BE: +            return 3; +             +        case SA_PCM_FORMAT_S32_LE: +        case SA_PCM_FORMAT_S32_BE: +        case SA_PCM_FORMAT_FLOAT32_LE: +        case SA_PCM_FORMAT_FLOAT32_BE: +            return 4; + +        case _SA_PCM_FORMAT_MAX: +            ; +    } + +    sa_assert_not_reached(); +} + +static int meta_check_png(const void *data, size_t size) { +    static const uint8_t png_signature[] = { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }; +    sa_assert(data); + +    if (size < sizeof(png_signature)) +        return 0; +     +    return memcmp(data, png_signature, 8) == 0; +} + +static int meta_check_utf8(const void *data, size_t size) { +    int32_t idx; +     +    oil_utf8_validate(&idx, data, size); + +    return (size_t) idx == size; +} + +static int meta_check_pid(const void *data, size_t size) { +    long int pid; +    char *t; + +    if (size <= 0) +        return 0; + +    if (memchr(data, 0, size)) +        return 0; +     +    if (!(t = sa_strndup(data, size))) +        return 0; +     +    errno = 0; +    pid = strtol(t, NULL, 10); +    sa_free(t); +     +    if (errno != 0) +        return 0; + +    if (pid <= 1) +        return 0; + +    return 1; +} + +static int meta_check_icon_name(const void *data, size_t size) { +    const char *t = data; + +    if (size <= 0) +        return 0; + +    if (memchr(data, 0, size)) +        return 0; +     +    if (size == 1 && t[0] == '.') +        return 0; + +    if (size == 2 && t[0] == '.' &&  t[1] == '.') +        return 0; + +    if (memchr(t, '/', size)) +        return 0; +     +    return 1; +} + +static int meta_check_word(const void *data, size_t size) { +    const char *t = data; + +    for (; size > 0; size --, t++) +        if (*t <= 32 || *t >= 127) +            return 0; +     +    return 1; +} + +typedef int (*meta_check_func_t)(const void *data, size_t size); + +int sa_stream_change_meta_data(sa_stream_t *s, const char *name, const void *data, size_t size) { +    void *d = NULL; +    const struct meta_name *m; +    int ret; + +    static const meta_check_func_t check_table[] = { +        meta_check_utf8, +        meta_check_pid, +        meta_check_word, /* FIXME */ +        meta_check_utf8, +        meta_check_icon_name, +        meta_check_png, +        meta_check_word, /* FIXME */ +        meta_check_word, /* FIXME */ +    }; +         +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(name, SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +    sa_return_val_if_fail_mutex(s->mutex, data || size == 0, SA_ERROR_INVALID); + +    if (!(m = sa_lookup_meta_name(name, strlen(name)))) { +        sa_mutex_unlock(s->mutex); +        return SA_ERROR_NO_META; +    } + +    if (!check_table[m->idx](data, size)) { +        sa_mutex_unlock(s->mutex); +        return SA_ERROR_INVALID; +    } + +    if (data) +        if (!(d = sa_memdup(data, size))) { +            sa_mutex_unlock(s->mutex); +            return SA_ERROR_OOM; +        } + +    ret = s->state == SA_STATE_INIT ? SA_SUCCESS : driver_change_meta_data(s, name, data, size); + +    if (ret == SA_SUCCESS) { +        sa_free(s->meta_data[m->idx]); +        s->meta_data[m->idx] = d; +        s->meta_data_size[m->idx] = size; +    } else +        sa_free(d); +     +    sa_mutex_unlock(s->mutex); +    return ret; +} + +int sa_stream_get_meta_data(sa_stream_t *s, const char *name, void *data, size_t *size) { +    const struct meta_name *m; + +    sa_return_val_if_fail(s, SA_ERROR_INVALID); +    sa_return_val_if_fail(name, SA_ERROR_INVALID); +    sa_return_val_if_fail(size && (*size == 0 || data), SA_ERROR_INVALID); +    sa_mutex_lock(s->mutex); +     +    if (!(m = sa_lookup_meta_name(name, strlen(name)))) { +        sa_mutex_unlock(s->mutex); +        return SA_ERROR_NO_META; +    } + +    if (!s->meta_data[m->idx]) { +        sa_mutex_unlock(s->mutex); +        return SA_ERROR_NO_DATA; +    } + +    if (*size < s->meta_data_size[m->idx]) { +        sa_mutex_unlock(s->mutex); +        return SA_ERROR_NO_SPACE; +    } + +    if (data) +        memcpy(data, s->meta_data[m->idx], s->meta_data_size[m->idx]); + +    *size = s->meta_data_size[m->idx]; + +    sa_mutex_unlock(s->mutex); +    return SA_SUCCESS; +} + +const char *sa_strerror(int code) { +    const char * const error_table[-_SA_ERROR_MAX] = { +        [-SA_SUCCESS] = "Success", +        [-SA_ERROR_NOT_SUPPORTED] = "Operation not supported", +        [-SA_ERROR_INVALID] = "Invalid argument", +        [-SA_ERROR_STATE] = "Invalid state", +        [-SA_ERROR_OOM] = "Out of memory", +        [-SA_ERROR_NO_DEVICE] = "No such device", +        [-SA_ERROR_NO_DRIVER] = "No such driver", +        [-SA_ERROR_NO_CODEC] = "No such codec", +        [-SA_ERROR_NO_PCM_FORMAT] = "No such PCM format", +        [-SA_ERROR_SYSTEM] = "System error", +        [-SA_ERROR_NO_INIT] = "Not initialized", +        [-SA_ERROR_NO_META] = "No such meta name", +        [-SA_ERROR_NO_DATA] = "No such data" +    }; + +    sa_return_val_if_fail(code <= 0, NULL); +    sa_return_val_if_fail(code > _SA_ERROR_MAX, NULL); + +    return error_table[-code]; +} diff --git a/src/common.h b/src/common.h new file mode 100644 index 0000000..b5f316c --- /dev/null +++ b/src/common.h @@ -0,0 +1,67 @@ +#ifndef foocommonh +#define foocommonh + +#include "sydney.h" +#include "mutex.h" + +#define _META_NAMES_MAX 9 + +typedef struct sa_pcm_attrs { +    sa_pcm_format_t format; +    unsigned rate; +    unsigned nchannels; +    sa_channel_t *channel_map; +} pcm_attrs_t; + +struct sa_stream { +    sa_mode_t mode; + +    pcm_attrs_t pcm_attrs; +    size_t pcm_sample_size; +    size_t pcm_frame_size; + +    char *codec; + +    size_t read_lower_watermark; +    size_t read_upper_watermark; +    size_t write_lower_watermark; +    size_t write_upper_watermark; + +    sa_xrun_mode_t xrun_mode; +    int ni_enabled; +    int dynamic_rate_enabled; +     +    sa_event_callback_t event_callback; + +    char *device; +    char *driver; +     +    int32_t *read_volume; +    int32_t *write_volume; + +    void *user_data; + +    sa_state_t state; + +    sa_adjust_t adjust_rate; +    sa_adjust_t adjust_nchannels; +    sa_adjust_t adjust_pcm_format; +    sa_adjust_t adjust_watermarks; + +    sa_error_t error; +    sa_notify_t notify; +    sa_event_t event; + +    void *private; /* driver specific data */ + +    void *meta_data[_META_NAMES_MAX]; +    size_t meta_data_size[_META_NAMES_MAX]; + +    sa_mutex_t *mutex; + +    sa_event_callback_t callback; +}; + +size_t sa_get_pcm_sample_size(sa_pcm_format_t f); + +#endif diff --git a/src/continued-fraction.c b/src/continued-fraction.c new file mode 100644 index 0000000..6cbf8a5 --- /dev/null +++ b/src/continued-fraction.c @@ -0,0 +1,69 @@ +/* + * Stolen from gnumeric + *  + * Original code from Morten Welinder <terra@gnome.org> + */ + +#include <stdio.h> +#include <limits.h> + +#include "continued-fraction.h" + +void sa_continued_fraction(double val, int max_denom, int *res_num, int *res_denom) { +    int n1, n2, d1, d2; +    double x, y; + +    if (val < 0) { +        sa_continued_fraction (-val, max_denom, res_num, res_denom); +        *res_num = -*res_num; +        return; +    } + +    n1 = 0; d1 = 1; +    n2 = 1; d2 = 0; + +    x = val; +    y = 1; + +    do { +        int a = (int) (x / y); +        double newy = x - a * y; +        int n3, d3; + +        if ((n2 && a > (INT_MAX - n1) / n2) || +            (d2 && a > (INT_MAX - d1) / d2) || +            a * d2 + d1 > max_denom) { +            *res_num = n2; +            *res_denom = d2; +            return; +        } + +        n3 = a * n2 + n1; +        d3 = a * d2 + d1; + +        x = y; +        y = newy; + +        n1 = n2; n2 = n3; +        d1 = d2; d2 = d3; +    } while (y > 1e-10); + +    *res_num = n2; +    *res_denom = d2; +} + +#if 0 + +int main(int argc, char*argv[]) { + +    float value = 3.1417235; +    int res_num, res_denom; + +    sa_continued_fraction(value, 0xFFFF, &res_num, &res_denom); + +    printf("%g ~= %i/%i = %g\n", value, res_num, res_denom, (float) res_num / res_denom); + +    return 0; +} + +#endif diff --git a/src/continued-fraction.h b/src/continued-fraction.h new file mode 100644 index 0000000..2026b50 --- /dev/null +++ b/src/continued-fraction.h @@ -0,0 +1,6 @@ +#ifndef foosydneycontinuedfractionhfoo +#define foosydneycontinuedfractionhfoo + +void sa_continued_fraction(double val, int max_denom, int *res_num, int *res_denom); + +#endif diff --git a/src/converter.c b/src/converter.c new file mode 100644 index 0000000..3b146ce --- /dev/null +++ b/src/converter.c @@ -0,0 +1,743 @@ +#include <math.h> +#include <string.h> + +#include "speex/speex_resampler.h" + +#include "converter.h" +#include "sydney.h" +#include "macro.h" +#include "common.h" +#include "format.h" +#include "volscale.h" +#include "byteswap.h" +#include "zero.h" +#include "add.h" +#include "bbuffer.h" +#include "continued-fraction.h" +#include "malloc.h" +#include "resample.h" + +/* Steps: byteswap -> convert -> volscale -> remap -> resample -> convert -> byteswap -> interleave */ + +/* Sample formats we know to process natively */ +static int native_pcm_format_process(sa_pcm_format_t f) { +    return +        f == SA_PCM_FORMAT_U8 || +        f == SA_PCM_FORMAT_S16_NE || +        f == SA_PCM_FORMAT_S32_NE || +        f == SA_PCM_FORMAT_FLOAT32_NE; +} + +/* Sample formats we know to resample natively  */ +static int native_pcm_format_resample(sa_pcm_format_t f) { +    return +        f == SA_PCM_FORMAT_S16_NE || +        f == SA_PCM_FORMAT_FLOAT32_NE; +} + +static sa_pcm_format_t byteswap_fix(sa_pcm_format_t f) { +     +    switch (f) { +        case SA_PCM_FORMAT_U8: +        case SA_PCM_FORMAT_ULAW: +        case SA_PCM_FORMAT_ALAW: +            return f; +             +        case SA_PCM_FORMAT_S16_NE: +        case SA_PCM_FORMAT_S16_RE: +            return SA_PCM_FORMAT_S16_NE; +                 +        case SA_PCM_FORMAT_S24_NE: +        case SA_PCM_FORMAT_S24_RE: +            return SA_PCM_FORMAT_S24_NE; +             +        case SA_PCM_FORMAT_S32_NE: +        case SA_PCM_FORMAT_S32_RE: +            return SA_PCM_FORMAT_S32_NE; + +        case SA_PCM_FORMAT_FLOAT32_NE: +        case SA_PCM_FORMAT_FLOAT32_RE: +            return SA_PCM_FORMAT_FLOAT32_NE; + +        case _SA_PCM_FORMAT_MAX: +            ; +    } + +    sa_assert_not_reached(); +} + +static sa_pcm_format_t get_work_format(sa_pcm_format_t a, sa_pcm_format_t b) { +     +    switch (a) { +        case SA_PCM_FORMAT_U8: +        case SA_PCM_FORMAT_ULAW: +        case SA_PCM_FORMAT_ALAW: +             +            switch (b) { +                case SA_PCM_FORMAT_U8: +                    return SA_PCM_FORMAT_U8; + +                case SA_PCM_FORMAT_ULAW: +                case SA_PCM_FORMAT_ALAW: +                case SA_PCM_FORMAT_S16_LE: +                case SA_PCM_FORMAT_S16_BE: +                    return SA_PCM_FORMAT_S16_NE; + +                case SA_PCM_FORMAT_S24_LE: +                case SA_PCM_FORMAT_S24_BE: +                case SA_PCM_FORMAT_S32_LE: +                case SA_PCM_FORMAT_S32_BE: +                    return SA_PCM_FORMAT_S32_NE; +                     +                case SA_PCM_FORMAT_FLOAT32_LE: +                case SA_PCM_FORMAT_FLOAT32_BE: +                    return SA_PCM_FORMAT_FLOAT32_NE; + +                case _SA_PCM_FORMAT_MAX: +                    ; +            } + +            break; +             +        case SA_PCM_FORMAT_S16_LE: +        case SA_PCM_FORMAT_S16_BE: + +            switch (b) { +                case SA_PCM_FORMAT_U8: +                case SA_PCM_FORMAT_ULAW: +                case SA_PCM_FORMAT_ALAW: +                case SA_PCM_FORMAT_S16_LE: +                case SA_PCM_FORMAT_S16_BE: +                    return SA_PCM_FORMAT_S16_NE; + +                case SA_PCM_FORMAT_S24_LE: +                case SA_PCM_FORMAT_S24_BE: +                case SA_PCM_FORMAT_S32_LE: +                case SA_PCM_FORMAT_S32_BE: +                    return SA_PCM_FORMAT_S32_NE; +                     +                case SA_PCM_FORMAT_FLOAT32_LE: +                case SA_PCM_FORMAT_FLOAT32_BE: +                    return SA_PCM_FORMAT_FLOAT32_NE; + +                case _SA_PCM_FORMAT_MAX: +                    ; +            } +            break; +             +        case SA_PCM_FORMAT_S24_LE: +        case SA_PCM_FORMAT_S24_BE: +        case SA_PCM_FORMAT_S32_LE: +        case SA_PCM_FORMAT_S32_BE: + +            switch (b) { +                case SA_PCM_FORMAT_U8: +                case SA_PCM_FORMAT_ULAW: +                case SA_PCM_FORMAT_ALAW: +                case SA_PCM_FORMAT_S16_LE: +                case SA_PCM_FORMAT_S16_BE: +                case SA_PCM_FORMAT_S24_LE: +                case SA_PCM_FORMAT_S24_BE: +                case SA_PCM_FORMAT_S32_LE: +                case SA_PCM_FORMAT_S32_BE: +                    return SA_PCM_FORMAT_S32_NE; +                     +                case SA_PCM_FORMAT_FLOAT32_LE: +                case SA_PCM_FORMAT_FLOAT32_BE: +                    return SA_PCM_FORMAT_FLOAT32_NE; + +                case _SA_PCM_FORMAT_MAX: +                    ; +            } +            break; +             +        case SA_PCM_FORMAT_FLOAT32_LE: +        case SA_PCM_FORMAT_FLOAT32_BE: +            return SA_PCM_FORMAT_FLOAT32_NE; + +        case _SA_PCM_FORMAT_MAX: +            ; +    } + +    sa_assert_not_reached(); +} + +static sa_pcm_format_t fix_work_format_for_resample(sa_pcm_format_t f) { + +    switch (f) { +        case SA_PCM_FORMAT_U8: +        case SA_PCM_FORMAT_S16_NE: +            return  SA_PCM_FORMAT_S16_NE; +            break; +             +        case SA_PCM_FORMAT_S32_NE: +        case SA_PCM_FORMAT_FLOAT32_NE: +            return SA_PCM_FORMAT_FLOAT32_NE; +            break; +             +        default: +            ; +    } + +    sa_assert_not_reached(); +} + +int sa_converter_init( +        sa_converter_t *c, +        const pcm_attrs_t *from, +        const pcm_attrs_t *to, +        int dynamic_rate_enabled) { + +    unsigned u, t; +    int resample_required; +     +    sa_assert(c); +    sa_assert(from); +    sa_assert(to); + +    memset(c, 0, sizeof(*c)); + +    c->from_pcm_format = from->format; +    c->to_pcm_format = to->format; + +    c->from_rate = from->rate; +    c->to_rate = to->rate; + +    c->from_nchannels = from->nchannels; +    c->to_nchannels = to->nchannels; + +    if (!(c->channel_map_table = sa_new(int, (from->nchannels+1) * to->nchannels))) +        goto fail; + +    for (u = 0; u < to->nchannels; u++) { +        unsigned k = 0; +         +        for (t = 0; t < from->nchannels; t++) { + +            if (from->channel_map[u] == to->channel_map[t]) { +                if (u != t) +                    c->remap_required = 1; +                 +                c->channel_map_table[u * (from->nchannels+1) + k++] += t; +            } +        } + +        if (k > 1) +            c->sum_required = 1; +         +        c->channel_map_table[k] = (unsigned) -1; +    } + +    if (c->from_nchannels != c->to_nchannels) +        c->remap_required = 1;     +     +    resample_required = +        from->rate != to->rate || +        dynamic_rate_enabled; + +    c->work_pcm_format = get_work_format(from->format, to->format); +    if (resample_required) +        c->work_pcm_format = fix_work_format_for_resample(c->work_pcm_format); +     +    sa_assert(native_pcm_format_process(c->work_pcm_format)); +    sa_assert(!resample_required || native_pcm_format_resample(c->work_pcm_format)); + +    c->from_sample_size = sa_get_pcm_sample_size(c->from_pcm_format); +    c->work_sample_size = sa_get_pcm_sample_size(c->work_pcm_format); +    c->to_sample_size = sa_get_pcm_sample_size(c->to_pcm_format); + +    /* Get function pointers */ +    c->pre_byteswap_func = sa_get_byteswap_func(from->format); + +    if (byteswap_fix(from->format) !=  c->work_pcm_format) { +        c->pre_format_func = sa_get_format_func(byteswap_fix(from->format), c->work_pcm_format); +        sa_assert(c->pre_format_func); +    } +         +    c->volscale_func = sa_get_volscale_func(c->work_pcm_format); +    sa_assert(c->volscale_func); +     +    c->zero_func = sa_get_zero_func(c->work_pcm_format); +    sa_assert(c->zero_func); +     +    c->add_func = sa_get_add_func(c->work_pcm_format); +    sa_assert(c->add_func); + +    if (resample_required) { +        c->resample_func = sa_get_resample_func(c->work_pcm_format); +        sa_assert(c->resample_func); +    }  + +    if (c->work_pcm_format != byteswap_fix(to->format)) { +        c->post_format_func = sa_get_format_func(c->work_pcm_format, byteswap_fix(to->format)); +        sa_assert(c->post_format_func); +    } +     +    c->post_byteswap_func = sa_get_byteswap_func(to->format); + +    c->interleave_func = sa_get_interleave_func(to->format); +    sa_assert(c->interleave_func); +     +    /* Initialize resampler */ + +    if (resample_required) { +        if (!(c->speex = speex_resampler_init(c->to_nchannels, c->from_rate, c->to_rate, SPEEX_RESAMPLER_QUALITY_DEFAULT, NULL))) +            goto fail; +    } + +    /* Initialize processing variables */ + +    if (!(c->from_process_data = sa_new0(void*, c->from_nchannels))) +        goto fail; + +    if (!(c->from_stride = sa_new0(size_t, c->from_nchannels))) +        goto fail; + +    if (!(c->to_process_data = sa_new0(void*, c->to_nchannels))) +        goto fail; + +    if (!(c->to_stride = sa_new0(size_t, c->to_nchannels))) +        goto fail; + +    /* Initialize volume stuff */ +    if (!(c->volume_factor = sa_new(int32_t, c->from_nchannels))) +        goto fail; + +    if (!(c->volume_divisor = sa_new(int32_t, c->from_nchannels))) +        goto fail; + +    c->no_volume = 1; + +    /* Initialize bounce buffers */ +     +    if (sa_bbuffer_init(&c->bb_pre_byteswap, c->from_nchannels, c->from_sample_size) < 0) +        goto fail; +    if (sa_bbuffer_init(&c->bb_pre_format, c->from_nchannels, c->work_sample_size) < 0) +        goto fail; +    if (sa_bbuffer_init(&c->bb_volscale, c->from_nchannels, c->work_sample_size) < 0) +        goto fail; +    if (sa_bbuffer_init(&c->bb_remap, c->to_nchannels, c->work_sample_size) < 0) +        goto fail; +    if (sa_bbuffer_init(&c->bb_resample, c->to_nchannels, c->work_sample_size) < 0) +        goto fail; +    if (sa_bbuffer_init(&c->bb_post_format, c->to_nchannels, c->to_sample_size) < 0) +        goto fail; +    if (sa_bbuffer_init(&c->bb_post_byteswap, c->to_nchannels, c->to_sample_size) < 0) +        goto fail; +    if (sa_bbuffer_init(&c->bb_interleave, c->to_nchannels, c->to_sample_size) < 0) +        goto fail; +    if (sa_bbuffer_init(&c->bb_tmp, 1, 1) < 0) +        goto fail; +     +    return 0; + +fail: +    sa_converter_done(c); + +    return SA_ERROR_OOM; +} + +void sa_converter_done(sa_converter_t *c) { +    sa_assert(c); + +    sa_free(c->channel_map_table); +     +    sa_free(c->from_process_data); +    sa_free(c->to_process_data); +    sa_free(c->from_stride); +    sa_free(c->to_stride); + +    sa_bbuffer_done(&c->bb_pre_byteswap); +    sa_bbuffer_done(&c->bb_pre_format); +    sa_bbuffer_done(&c->bb_volscale); +    sa_bbuffer_done(&c->bb_remap); +    sa_bbuffer_done(&c->bb_resample); +    sa_bbuffer_done(&c->bb_post_format); +    sa_bbuffer_done(&c->bb_post_byteswap); +    sa_bbuffer_done(&c->bb_interleave); +    sa_bbuffer_done(&c->bb_tmp); + +    if (c->speex) +        speex_resampler_destroy(c->speex); + +    sa_free(c->zero_buffer); + +    sa_free(c->volume_divisor); +    sa_free(c->volume_factor); +    memset(c, 0, sizeof(*c)); +} + +void* sa_converter_get_zero_buffer(sa_converter_t *c, size_t size) { +    void *b; +     +    sa_assert(c); +    sa_assert(size > 0); + +    if (c->zero_buffer && c->zero_size >= size) +        return c->zero_buffer; + +    sa_free(c->zero_buffer); + +    if (!(c->zero_buffer = sa_malloc(size))) +        return NULL; + +    c->zero_func(b, c->work_sample_size, size); +    return c->zero_func; +} + +int sa_converter_go( +        sa_converter_t *c, +        const void *const src[], const size_t sstr[], int sinterleave, +        void **dst[], size_t *dstr[], int dinterleave, +        size_t *size) { +     +    size_t* stride; +    void** process_data; +    int is_bounce; +    int interleave; +    unsigned i; +     +    sa_assert(c); + +    is_bounce = 0; +    stride = (size_t*) sstr; +    process_data = (void**) src; +    interleave = !!sinterleave; +    dinterleave = !!dinterleave; +     +    if (c->no_volume && +        !c->remap_required && +        !c->resample_func && +        c->from_pcm_format == c->to_pcm_format) { + +        /* We can shortcut this, since we don't need to do any real work.*/ + +        goto do_interleave; +    } +     +    if (c->pre_byteswap_func) { +        size_t k; +         +        k = dinterleave ? c->from_sample_size*c->from_nchannels : c->from_sample_size; +         +        for (i = 0; i < c->from_nchannels; i++) { +            void *b; + +            if (!(b = sa_bbuffer_get(&c->bb_pre_byteswap, i, *size, dinterleave))) +                return SA_ERROR_OOM; +             +            c->pre_byteswap_func(b, k, process_data[i], stride[i], *size); +            c->from_process_data[i] = b; +            c->from_stride[i] = k; +        } + +        process_data = c->from_process_data; +        stride = c->from_stride; +        interleave = dinterleave; +        is_bounce = 1; +    } +     +    if (c->pre_format_func) { + +        if (is_bounce && c->from_sample_size == c->to_sample_size) { + +            /* The data to process is already in a bounce buffer, we +             * can do this in-place */ + +            for (i = 0; i < c->from_nchannels; i++) +                c->pre_format_func(&c->bb_tmp, process_data[i], stride[i], process_data[i], stride[i], *size); +             +        } else { +            size_t k, new_size; +         +            new_size = *size / c->from_sample_size * c->work_sample_size; +            k = dinterleave ? c->work_sample_size*c->from_nchannels : c->work_sample_size; +             +            for (i = 0; i < c->from_nchannels; i++) { +                void *b; +                 +                if (!(b = sa_bbuffer_get(&c->bb_pre_format, i, new_size, dinterleave))) +                    return SA_ERROR_OOM; +                 +                c->pre_format_func(&c->bb_tmp, b, k, process_data[i], stride[i], *size); +                c->from_process_data[i] = b; +                c->from_stride[i] = k; +            } +             +            process_data = c->from_process_data; +            stride = c->from_stride; +            *size = new_size; +            interleave = dinterleave; +            is_bounce = 1; +        } +    } + +    if (!c->no_volume) { + +        sa_assert(c->volscale_func); + +        if (is_bounce) { + +            /* The data to process is already in a bounce buffer, we +             * can do this in-place */ +             +            for (i = 0; i < c->from_nchannels; i++); +                c->volscale_func(process_data[i], stride[i], process_data[i], stride[i], c->volume_factor[i], c->volume_divisor[i], *size); + +        } else { +            size_t k; + +            k = dinterleave ? c->work_sample_size*c->from_nchannels : c->work_sample_size; + +            for (i = 0; i < c->from_nchannels; i++) { +                void *b; +                 +                if (!(b = sa_bbuffer_get(&c->bb_volscale, i, *size, dinterleave))) +                    return SA_ERROR_OOM; +                 +                c->volscale_func(b, k, process_data[i], stride[i], c->volume_factor[i], c->volume_divisor[i], *size); +                c->from_process_data[i] = b; +                c->from_stride[i] = k; +            } +             +            process_data = c->from_process_data; +            stride = c->from_stride; +            interleave = dinterleave; +            is_bounce = 1; +        } +    } + +    if (c->remap_required) { +        size_t k; +        int need_proper_interleave = 0; + +        k = dinterleave ? c->work_sample_size*c->to_nchannels : c->work_sample_size; + +        for (i = 0; i < c->to_nchannels; i++) { +            void *b; +            int *p = &c->channel_map_table[i * (c->from_nchannels+1)]; +             +            if (p[0] == -1) { +                /* We have to write silence to this channel */ + +                if (!(b = sa_converter_get_zero_buffer(c, *size))) +                    return SA_ERROR_OOM; + +                c->to_process_data[i] = b; +                c->to_stride[i] = c->work_sample_size; + +                need_proper_interleave = 1; +            } else if (p[1] == -1) { +                /* Just one channel, nothing to mix */ + +                c->to_process_data[i] = process_data[p[0]]; +                c->to_stride[i] = stride[p[0]]; + +                need_proper_interleave = 1; +            } else { +                int j; +                 +                /* We have to mix two or more channels */  + +                if (!(b = sa_bbuffer_get(&c->bb_remap, i, *size, dinterleave))) +                    return SA_ERROR_OOM; + +                c->add_func(b, k, process_data[p[0]], stride[p[0]], process_data[p[1]], stride[p[1]], *size); + +                for (j = 2; p[j] != -1; j++) +                    c->add_func(b, k, b, k, process_data[p[j]], stride[p[j]], *size); +                 +                c->to_process_data[i] = b; +                c->to_stride[i] = k; +            } +        } + +        process_data = c->to_process_data; +        stride = c->to_stride; +        interleave = need_proper_interleave ? -1 : dinterleave; +        is_bounce = 1; +    } + +    if (c->resample_func) { +        size_t k; +        size_t new_size; + +        k = dinterleave ? c->work_sample_size*c->to_nchannels : c->work_sample_size; + +        new_size = (size_t) (((((uint64_t) *size+c->work_sample_size-1)/c->work_sample_size)*c->to_rate)/c->from_rate+1)*c->work_sample_size; /* FIXME */ +         +        for (i = 0; i < c->to_nchannels; i++) { +            void *b; + +            if (!(b = sa_bbuffer_get(&c->bb_resample, i, new_size, dinterleave))) +                return SA_ERROR_OOM; + +            c->resample_func(c->speex, i, b, k, process_data[i], stride[i], *size, &new_size); +            c->to_process_data[i] = b; +            c->to_stride[i] = k; +        } + +        process_data = c->to_process_data; +        stride = c->to_stride; +        *size = new_size; +        interleave = dinterleave; +        is_bounce = 1; +    } + +    if (c->post_format_func) { + +        if (is_bounce && c->work_sample_size == c->to_sample_size) { + +            /* The data to process is already in a bounce buffer, we +             * can do this in-place */ +             +            for (i = 0; i < c->to_nchannels; i++) +                c->post_format_func(&c->bb_tmp, process_data[i], stride[i], process_data[i], stride[i], *size); + +        } else { +            size_t k, new_size; + +            k = dinterleave ? c->to_sample_size*c->to_nchannels : c->to_sample_size; +            new_size = *size / c->work_sample_size * c->to_sample_size; +         +            for (i = 0; i < c->to_nchannels; i++) { +                void *b; +                 +                if (!(b = sa_bbuffer_get(&c->bb_post_format, i, new_size, dinterleave))) +                    return SA_ERROR_OOM; +                 +                c->post_format_func(&c->bb_tmp, b, k, process_data[i], stride[i], *size); +                c->to_process_data[i] = b; +                c->to_stride[i] = k; +            } +             +            process_data = c->to_process_data; +            stride = c->to_stride; +            *size = new_size; +            interleave = dinterleave; +            is_bounce = 1; +        } +    } +     +    if (c->post_byteswap_func) { + +        if (is_bounce) { + +            /* The data to process is already in a bounce buffer, we +             * can do this in-place */ +             +            for (i = 0; i < c->to_nchannels; i++) +                c->post_byteswap_func(process_data[i], stride[i], process_data[i], stride[i], *size); + +        } else { +            size_t k; + +            k = dinterleave ? c->to_sample_size*c->to_nchannels : c->to_sample_size; +         +            for (i = 0; i < c->to_nchannels; i++) { +                void *b; +                 +                if (!(b = sa_bbuffer_get(&c->bb_post_byteswap, i, *size, dinterleave))) +                    return SA_ERROR_OOM; +                 +                c->post_byteswap_func(b, k, process_data[i], stride[i], *size); +                 +                c->to_process_data[i] = b; +                c->to_stride[i] = k; +            } + +            process_data = c->to_process_data; +            stride = c->to_stride; +            interleave = dinterleave; +            is_bounce = 1; +        } +    } + +do_interleave: +     +    if (interleave != dinterleave) { +        size_t k; + +        k = dinterleave ? c->to_sample_size*c->to_nchannels : c->to_sample_size; + +        for (i = 0; i < c->to_nchannels; i++) { +            void *b; +             +            if (!(b = sa_bbuffer_get(&c->bb_interleave, i, *size, dinterleave))) +                return SA_ERROR_OOM; +             +            c->interleave_func(b, k, process_data[i], stride[i], *size); +             +            c->to_process_data[i] = b; +            c->to_stride[i] = k; +        } +         +        process_data = c->to_process_data; +        stride = c->to_stride; +        interleave = dinterleave; +        is_bounce = 1; +    } + +    *dstr = stride; +    *dst = process_data; + +    return SA_SUCCESS; +} + +void sa_converter_set_volume(sa_converter_t *c, const int32_t vol[]) { +    unsigned i; +    int no_volume = 1; +     +    sa_assert(c); + +    for (i = 0; i < c->from_nchannels; i++) { +        int num, denom; + +        if (vol[i] == 0) { +            c->volume_factor[i] = 1; +            c->volume_divisor[i] = 1; +        } else if (vol[i] <= SA_VOLUME_MUTED) { +            c->volume_factor[i] = 0; +            c->volume_divisor[i] = 1; +            no_volume = 0; +        } else { +            float f = powf(10.0, (float) vol[i] / 2000); +             +            sa_continued_fraction(f, 0x7FFF, &num, &denom); +             +            if (num != 1 || denom != 1) +                no_volume = 0; +             +            c->volume_factor[i] = (int32_t) num; +            c->volume_divisor[i] = (int32_t) denom; +        } +    } + +    c->no_volume = no_volume; +} + +int sa_converter_go_interleaved( +        sa_converter_t *c, +        const void *const data,  +        void **dst[], size_t *dstr[], int dinterleave, +        size_t *size) { + +    unsigned i; +    const uint8_t *d = data; +    unsigned stride = c->from_nchannels * c->from_sample_size; + +    for (i = 0; i < c->from_nchannels; i++) { +        c->from_process_data[i] = (void*) data; +        d += c->from_sample_size; +        c->from_stride[i] = stride; +    } + +    return sa_converter_go(c, (const void *const*) c->from_process_data, c->from_stride, 1, dst, dstr, dinterleave, size); +} + +void sa_converter_set_ratio(sa_converter_t *c, unsigned rate1, unsigned rate2) { +    assert(c); +    assert(c->speex); + +    speex_resampler_set_rate(c->speex, rate1, rate2); +} diff --git a/src/converter.h b/src/converter.h new file mode 100644 index 0000000..8112231 --- /dev/null +++ b/src/converter.h @@ -0,0 +1,82 @@ +#ifndef foosydneyconverterhfoo +#define foosydneyconverterhfoo + +#include "sydney.h" +#include "volscale.h" +#include "byteswap.h" +#include "zero.h" +#include "add.h" +#include "bbuffer.h" +#include "resample.h" +#include "format.h" +#include "common.h" +#include "interleave.h" + +typedef struct sa_converter sa_converter_t; + +struct sa_converter { +    sa_pcm_format_t from_pcm_format, to_pcm_format; +    unsigned from_nchannels, to_nchannels; +    unsigned from_rate, to_rate; + +    int sum_required; +    int remap_required; +     +    sa_pcm_format_t work_pcm_format; +     +    size_t from_sample_size, work_sample_size, to_sample_size; + +    sa_byteswap_func_t pre_byteswap_func, post_byteswap_func; +    sa_format_func_t pre_format_func, post_format_func; +    sa_volscale_func_t volscale_func; +    sa_zero_func_t zero_func; +    sa_add_func_t add_func; +    sa_resample_func_t resample_func; +    sa_interleave_func_t interleave_func; + +    SpeexResamplerState *speex; + +    sa_bbuffer_t bb_pre_byteswap, +        bb_pre_format, +        bb_volscale, +        bb_remap, +        bb_resample, +        bb_post_format, +        bb_post_byteswap, +        bb_interleave, +        bb_tmp; + +    void **from_process_data, **to_process_data; +    size_t *from_stride, *to_stride; + +    int32_t *volume_factor, *volume_divisor; +    int no_volume; + +    int *channel_map_table; + +    void *zero_buffer; +    size_t zero_size; +}; + +int sa_converter_init(sa_converter_t *c, const pcm_attrs_t *from, const pcm_attrs_t *to, int dynamic_rate_enabled); +void sa_converter_done(sa_converter_t *c); + +int sa_converter_go( +        sa_converter_t *c, +        const void *const src[], const size_t sstr[], int sinterleave, +        void **dst[], size_t *dstr[], int dinterleave, +        size_t *size); + +int sa_converter_go_interleaved( +        sa_converter_t *c, +        const void *const data,  +        void **dst[], size_t *dstr[], int dinterleave, +        size_t *size); + +void sa_converter_set_volume(sa_converter_t *c, const int32_t vol[]); + +void sa_converter_set_ratio(sa_converter_t *c, unsigned rate1, unsigned rate2); + +void* sa_converter_get_zero_buffer(sa_converter_t *c, size_t size); + +#endif diff --git a/src/driver.h b/src/driver.h new file mode 100644 index 0000000..be5d4b8 --- /dev/null +++ b/src/driver.h @@ -0,0 +1,34 @@ +#ifndef foodriverhfoo +#define foodriverhfoo + +#include "sydney.h" + +int driver_open(sa_stream_t *dev); +int driver_destroy(sa_stream_t *dev); + +int driver_start_thread(sa_stream_t *dev, sa_event_callback_t callback); +int driver_stop_thread(sa_stream_t *dev); + +int driver_change_device(sa_stream_t *dev, const char *device_name); +int driver_change_read_volume(sa_stream_t *dev, const int32_t vol[]); +int driver_change_write_volume(sa_stream_t *dev, const int32_t vol[]); +int driver_change_rate(sa_stream_t *dev, unsigned rate); +int driver_change_meta_data(sa_stream_t *dev, const char *name, const void *data, size_t size); + +int driver_get_state(sa_stream_t *dev, sa_state_t *state); +int driver_get_position(sa_stream_t *dev, sa_position_t position, int64_t *pos); + +int driver_read(sa_stream_t *dev, void *data, size_t nbytes); +int driver_read_ni(sa_stream_t *dev, unsigned channel, void *data, size_t nbytes); + +int driver_pwrite(sa_stream_t *dev, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence); +int driver_pwrite_ni(sa_stream_t *dev, unsigned channel, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence); + +int driver_get_read_size(sa_stream_t *dev, size_t *size); +int driver_get_write_size(sa_stream_t *dev, size_t *size); + +int driver_resume(sa_stream_t *dev); +int driver_pause(sa_stream_t *dev); +int driver_drain(sa_stream_t *dev); + +#endif diff --git a/src/format.c b/src/format.c new file mode 100644 index 0000000..f7a8755 --- /dev/null +++ b/src/format.c @@ -0,0 +1,438 @@ +#include <inttypes.h> +#include <sys/types.h> + +#include <liboil/liboil.h> + +#include "format.h" +#include "g711.h" +#include "macro.h" + +/* u8 --> */ + +static int format_u8_to_s16(sa_bbuffer_t *b, void *dst, size_t dstr, const void *src, size_t sstr, size_t bytes) { +    int16_t d = -0x80, f = 0x100; +     +    oil_conv_s16_u8(dst, dstr, src, sstr, bytes); +    oil_scalaradd_s16(dst, dstr, dst, dstr, &d, bytes); +    oil_scalarmult_s16(dst, dstr, dst, dstr, &f, bytes); + +    return SA_SUCCESS; +} + +static int format_u8_to_s32(sa_bbuffer_t *b, void *dst, size_t dstr, const void *src, size_t sstr, size_t bytes) { +    int32_t d = -0x80, f = 0x1000000; +     +    oil_conv_s16_u8(dst, dstr, src, sstr, bytes); +    oil_scalaradd_s32(dst, dstr, dst, dstr, &d, bytes); +    oil_scalarmult_s32(dst, dstr, dst, dstr, &f, bytes); + +    return SA_SUCCESS; +} + +static int format_u8_to_f32(sa_bbuffer_t *b, void *dst, size_t dstr, const void *src, size_t sstr, size_t bytes) { +    float d = -0x80, f = 1.0/0x7F; + +    oil_conv_f32_u8(dst, dstr, src, sstr, bytes); +    oil_scalaradd_f32(dst, dstr, dst, dstr, &d, bytes); +    oil_scalarmult_f32(dst, dstr, dst, dstr, &f, bytes);                        + +    return SA_SUCCESS; +} + +/* ulaw --> */ + +static int format_ulaw_to_s16(sa_bbuffer_t *b, void *dst, size_t dstr, const void *src, size_t sstr, size_t bytes) { +    int16_t *d = dst; +    const uint8_t *s = src; + +    for (; bytes > 0; bytes --, d += dstr/sizeof(int16_t), s += sstr) +        *d = sa_ulaw2linear16(*s); + +    return SA_SUCCESS; +} + +static int format_ulaw_to_s32(sa_bbuffer_t *b, void *dst, size_t dstr, const void *src, size_t sstr, size_t bytes) { +    int32_t *d = dst; +    const uint8_t *s = src; + +    for (; bytes > 0; bytes --, d += dstr/sizeof(int32_t), s += sstr) +        *d = (int32_t) sa_ulaw2linear16(*s) * 0x10000; + +    return SA_SUCCESS; +} + +static int format_ulaw_to_f32(sa_bbuffer_t *b, void *dst, size_t dstr, const void *src, size_t sstr, size_t bytes) { +    float *d = dst; +    const uint8_t *s = src; + +    for (; bytes > 0; bytes --, d += dstr/sizeof(float), s += sstr) +        *d = sa_ulaw2linear16(*s * 1.0F / 0x7FFF); + +    return SA_SUCCESS; +} + +/* alaw --> */ + +static int format_alaw_to_s16(sa_bbuffer_t *b, void *dst, size_t dstr, const void *src, size_t sstr, size_t bytes) { +    int16_t *d = dst; +    const uint8_t *s = src; + +    for (; bytes > 0; bytes --, d += dstr/sizeof(int16_t), s += sstr) +        *d = sa_alaw2linear16(*s); + +    return SA_SUCCESS; +} + +static int format_alaw_to_s32(sa_bbuffer_t *b, void *dst, size_t dstr, const void *src, size_t sstr, size_t bytes) { +    int32_t *d = dst; +    const uint8_t *s = src; + +    for (; bytes > 0; bytes --, d += dstr/sizeof(int32_t), s += sstr) +        *d = (int32_t) sa_alaw2linear16(*(s++)) * 0x10000; + +    return SA_SUCCESS; +} + +static int format_alaw_to_f32(sa_bbuffer_t *b, void *dst, size_t dstr, const void *src, size_t sstr, size_t bytes) { +    float *d = dst; +    const uint8_t *s = src; + +    for (; bytes > 0; bytes --, d += dstr/sizeof(float), s += sstr) +        *d = sa_alaw2linear16(*(s++) * 1.0F / 0x7FFF); + +    return SA_SUCCESS; +} + +/* s16 --> */ + +static int format_s16_to_u8(sa_bbuffer_t *b, void *dst, size_t dstr, const void *src, size_t sstr, size_t bytes) { +    uint8_t *d = dst; +    const int16_t *s = src; +    unsigned n = bytes/sizeof(int16_t); + +    for (; n > 0; n--, d += dstr, s += sstr/sizeof(int16_t)) +        *d = (uint8_t) (*s / 0x100 + 0x80); +     +    return SA_SUCCESS; +} + +static int format_s16_to_ulaw(sa_bbuffer_t *b, void *dst, size_t dstr, const void *src, size_t sstr, size_t bytes) { +    uint8_t *d = dst; +    const int16_t *s = src; +    unsigned n = bytes/sizeof(int16_t); + +    for (; n > 0; n --, d += dstr, s += sstr/sizeof(int16_t)) +        *d = sa_14linear2ulaw(*s); + +    return SA_SUCCESS; +} + +static int format_s16_to_alaw(sa_bbuffer_t *b, void *dst, size_t dstr, const void *src, size_t sstr, size_t bytes) { +    uint8_t *d = dst; +    const int16_t *s = src; +    unsigned n = bytes/sizeof(int16_t); + +    for (; n > 0; n --, d += dstr, s += sstr/sizeof(int16_t)) +        *d = sa_13linear2alaw(*s); + +    return SA_SUCCESS; +} + +static int format_s16_to_s32(sa_bbuffer_t *b, void *dst, size_t dstr, const void *src, size_t sstr, size_t bytes) { +    int f = 0x10000; +    unsigned n = bytes/sizeof(int16_t); + +    oil_conv_s32_s16(dst, dstr, src, sstr, n); +    oil_scalarmult_s32(dst, dstr, dst, dstr, &f, n);                        + +    return SA_SUCCESS; +} + +static int format_s16_to_f32(sa_bbuffer_t *b, void *dst, size_t dstr, const void *src, size_t sstr, size_t bytes) { +    float f = 1.0/0x7ffff; +    unsigned n = bytes/sizeof(int16_t); +     +    oil_conv_f32_s16(dst, dstr, src, sstr, n); +    oil_scalarmult_f32(dst, dstr, dst, dstr, &f, n);                        + +    return SA_SUCCESS; +} + +/* s24 --> */ + +static int format_s24_to_s32(sa_bbuffer_t *b, void *dst, size_t dstr, const void *src, size_t sstr, size_t bytes) { +    int32_t *d = dst; +    const uint8_t *s = src; +    unsigned n = bytes/3; + +    for (; n > 0; n--, d += dstr/sizeof(int32_t), s += sstr/3) +#if defined(SA_LITTLE_ENDIAN) +        *d = (int32_t) ((int8_t) s[2]) * 0x1000000 + s[1] * 0x10000 + s[0] * 0x100; +#elif defined(SA_BIG_ENDIAN) +        *d = (int32_t) ((int8_t) s[0]) * 0x1000000 + s[1] * 0x10000 + s[2] * 0x100; +#else +#error "Unknown byte order" +#endif +     +    return SA_SUCCESS; +} + +static int format_s24_to_f32(sa_bbuffer_t *b, void *dst, size_t dstr, const void *src, size_t sstr, size_t bytes) { +    float *d = dst; +    const uint8_t *s = src; +    unsigned n = bytes/3; + +    for (; n > 0; n--, d += dstr/sizeof(float), s += sstr/3) +#if defined(SA_LITTLE_ENDIAN) +        *d = ((float) ((int8_t) s[2]) * 0x10000 + s[1] * 0x100 + s[0]) / 0x7fffff; +#elif defined(SA_BIG_ENDIAN) +        *d = ((float) ((int8_t) s[0]) * 0x10000 + s[1] * 0x100 + s[2]) / 0x7fffff; +#else +#error "Unknown byte order" +#endif +     +    return SA_SUCCESS; +} + +/* s32 --> */ + +static int format_s32_to_u8(sa_bbuffer_t *b, void *dst, size_t dstr, const void *src, size_t sstr, size_t bytes) { +    uint8_t *d = dst; +    const int32_t *s = src; +    unsigned n = bytes/sizeof(int32_t); + +    for (; n > 0; n--, d += dstr, s += sstr/sizeof(int32_t)) +        *d = (uint8_t) (*s / 0x1000000 + 0x80); +     +    return SA_SUCCESS; +} + +static int format_s32_to_ulaw(sa_bbuffer_t *b, void *dst, size_t dstr, const void *src, size_t sstr, size_t bytes) { +    uint8_t *d = dst; +    const int32_t *s = src; +    unsigned n = bytes/sizeof(int32_t); + +    for (; n > 0; n--, d += dstr, s += sstr/sizeof(int32_t)) +        *d = sa_14linear2ulaw(*s / 0x10000); + +    return SA_SUCCESS; +} + +static int format_s32_to_alaw(sa_bbuffer_t *b, void *dst, size_t dstr, const void *src, size_t sstr, size_t bytes) { +    uint8_t *d = dst; +    const int32_t *s = src; +    unsigned n = bytes/sizeof(int32_t); + +    for (; n > 0; n--, d += dstr, s += sstr/sizeof(int32_t)) +        *d = sa_13linear2alaw(*s / 0x10000); + +    return SA_SUCCESS; +} + +static int format_s32_to_s16(sa_bbuffer_t *b, void *dst, size_t dstr, const void *src, size_t sstr, size_t bytes) { +    int16_t *d = dst; +    const int32_t *s = src; +    unsigned n = bytes/sizeof(int32_t); + +    for (; n > 0; n--, d += dstr/sizeof(int16_t), s += sstr/sizeof(int32_t)) +        *d = (int16_t) (*s / 0x10000); +     +    return SA_SUCCESS; +} + +static int format_s32_to_s24(sa_bbuffer_t *b, void *dst, size_t dstr, const void *src, size_t sstr, size_t bytes) { +    uint8_t *d = dst; +    const int32_t *s = src; +    unsigned n = bytes/sizeof(float); + +    for (; n > 0; n--, d += dstr/3, s += sstr/sizeof(int32_t)) { +        uint32_t j = (uint32_t) (*s) >> 8; +         +#if defined(SA_LITTLE_ENDIAN) +        d[0] = j & 0xFF; +        d[1] = (j >> 8) & 0xFF; +        d[2] = (j >> 16); +#elif defined(SA_BIG_ENDIAN) +        d[2] = j & 0xFF; +        d[1] = (j >> 8) & 0xFF; +        d[0] = (j >> 16); +#else +#error "Unknown byte order" +#endif +    } +     +    return SA_SUCCESS; +} + +static int format_s32_to_f32(sa_bbuffer_t *b, void *dst, size_t dstr, const void *src, size_t sstr, size_t bytes) { +    float f = 1.0/0x7fffffff; +    unsigned n = bytes/sizeof(int32_t); +     +    oil_conv_f32_s32(dst, dstr, src, sstr, n); +    oil_scalarmult_f32(dst, dstr, dst, dstr, &f, n);                        + +    return SA_SUCCESS; +} + +/* f32 --> */ + +static int format_f32_to_u8(sa_bbuffer_t *b, void *dst, size_t dstr, const void *src, size_t sstr, size_t bytes) { +    uint8_t *d = dst; +    const float *s = src; +    float *buf; +    float f = 0x7F, p = 0x80; +    unsigned n = bytes/sizeof(float); + +    if (!(buf = sa_bbuffer_get(b, 0, bytes, 1))) +        return SA_ERROR_OOM; + +    oil_scalarmult_f32(buf, sizeof(float), s, sstr, &f, n); +    oil_scalaradd_f32(buf, sizeof(float), buf, sizeof(float), &p, n); +    oil_clipconv_u8_f32(d, dstr, buf, sizeof(float), n); + +    return SA_SUCCESS; +} + +static int format_f32_to_ulaw(sa_bbuffer_t *b, void *dst, size_t dstr, const void *src, size_t sstr, size_t bytes) { +    uint8_t *d = dst; +    const float *s = src; +    unsigned n = bytes/sizeof(float); + +    for (; n > 0; n --, d += dstr, s += sstr/sizeof(float)) { +        float v = *s * 0x7FFF; +        if (v < -0x8000) v = -0x8000; +        if (v > -0x7FFF) v = -0x7FFF; +        *d = sa_13linear2alaw((int16_t) v); +    } + +    return SA_SUCCESS; +} + +static int format_f32_to_alaw(sa_bbuffer_t *b, void *dst, size_t dstr, const void *src, size_t sstr, size_t bytes) { +    uint8_t *d = dst; +    const float *s = src; +    unsigned n = bytes/sizeof(float); +     +    for (; n > 0; n --, d += dstr, s += sstr/sizeof(float)) { +        float v = *s * 0x7FFF; +        if (v < -0x8000) v = -0x8000; +        if (v > -0x7FFF) v = -0x7FFF; +        *d = sa_13linear2alaw((int16_t) v); +    } + +    return SA_SUCCESS; +} + +static int format_f32_to_s16(sa_bbuffer_t *b, void *dst, size_t dstr, const void *src, size_t sstr, size_t bytes) { +    int16_t *d = dst; +    const float *s = src; +    float *buf; +    float f = 0x7FFF; +    unsigned n = bytes/sizeof(float); + +    if (!(buf = sa_bbuffer_get(b, 0, bytes, 1))) +        return SA_ERROR_OOM; + +    oil_scalarmult_f32(buf, sizeof(float), s, sstr, &f, n);                        +    oil_clipconv_s16_f32(d, dstr, buf, sizeof(float), n); + +    return SA_SUCCESS; +} + +static int format_f32_to_s24(sa_bbuffer_t *b, void *dst, size_t dstr, const void *src, size_t sstr, size_t bytes) { +    uint8_t *d = dst; +    const float *s = src; +    unsigned n = bytes/sizeof(float); + +    for (; n > 0; n--, d += dstr/3, s += sstr/sizeof(float)) { +        float f = *s / 0x7fffff; +        uint32_t j; + +        if (f >  0x7fffff) f =  0x7fffff; +        if (f < -0x800000) f = -0x800000; + +        j = (uint32_t) ((int32_t) f); +         +#if defined(SA_LITTLE_ENDIAN) +        d[0] = j & 0xFF; +        d[1] = (j >> 8) & 0xFF; +        d[2] = (j >> 16); +#elif defined(SA_BIG_ENDIAN) +        d[2] = j & 0xFF; +        d[1] = (j >> 8) & 0xFF; +        d[0] = (j >> 16); +#else +#error "Unknown byte order" +#endif +    } +     +    return SA_SUCCESS; +} + +static int format_f32_to_s32(sa_bbuffer_t *b, void *dst, size_t dstr, const void *src, size_t sstr, size_t bytes) { +    int32_t *d = dst; +    const float *s = src; +    float *buf; +    float f = 0x7FFFFFFF; +    unsigned n = bytes/sizeof(float); + +    if (!(buf = sa_bbuffer_get(b, 0, bytes, 1))) +        return SA_ERROR_OOM; + +    oil_scalarmult_f32(buf, sizeof(float), s, sstr, &f, n);                        +    oil_clipconv_s32_f32(d, dstr, buf, sizeof(float), n); + +    return SA_SUCCESS; +} + +sa_format_func_t sa_get_format_func(sa_pcm_format_t from, sa_pcm_format_t to) { + +    /* Rules: we need conversion functions: +     * +     *  1. from all formats to all "better" work formats +     *  2. from all work formats to all "lower" formats +     *  3. only for NE types +     */ +     +    static const sa_format_func_t funcs[_SA_PCM_FORMAT_MAX * _SA_PCM_FORMAT_MAX] = { +        [_SA_PCM_FORMAT_MAX * SA_PCM_FORMAT_U8         + SA_PCM_FORMAT_S16_NE    ] = format_u8_to_s16,      /* done */ +        [_SA_PCM_FORMAT_MAX * SA_PCM_FORMAT_U8         + SA_PCM_FORMAT_S32_NE    ] = format_u8_to_s32,      /* done */ +        [_SA_PCM_FORMAT_MAX * SA_PCM_FORMAT_U8         + SA_PCM_FORMAT_FLOAT32_NE] = format_u8_to_f32,      /* done */ + +        [_SA_PCM_FORMAT_MAX * SA_PCM_FORMAT_ULAW       + SA_PCM_FORMAT_S16_NE    ] = format_ulaw_to_s16,    /* done, no liboil */ +        [_SA_PCM_FORMAT_MAX * SA_PCM_FORMAT_ULAW       + SA_PCM_FORMAT_S32_NE    ] = format_ulaw_to_s32,    /* done, no liboil */ +        [_SA_PCM_FORMAT_MAX * SA_PCM_FORMAT_ULAW       + SA_PCM_FORMAT_FLOAT32_NE] = format_ulaw_to_f32,    /* done, no liboil */ + +        [_SA_PCM_FORMAT_MAX * SA_PCM_FORMAT_ALAW       + SA_PCM_FORMAT_S16_NE    ] = format_alaw_to_s16,    /* done, no liboil */ +        [_SA_PCM_FORMAT_MAX * SA_PCM_FORMAT_ALAW       + SA_PCM_FORMAT_S32_NE    ] = format_alaw_to_s32,    /* done, no liboil */ +        [_SA_PCM_FORMAT_MAX * SA_PCM_FORMAT_ALAW       + SA_PCM_FORMAT_FLOAT32_NE] = format_alaw_to_f32,    /* done, no liboil */ + +        [_SA_PCM_FORMAT_MAX * SA_PCM_FORMAT_S16_NE     + SA_PCM_FORMAT_U8        ] = format_s16_to_u8,      /* done, no liboil */ +        [_SA_PCM_FORMAT_MAX * SA_PCM_FORMAT_S16_NE     + SA_PCM_FORMAT_ULAW      ] = format_s16_to_ulaw,    /* done, no liboil */ +        [_SA_PCM_FORMAT_MAX * SA_PCM_FORMAT_S16_NE     + SA_PCM_FORMAT_ALAW      ] = format_s16_to_alaw,    /* done, no liboil */ +        [_SA_PCM_FORMAT_MAX * SA_PCM_FORMAT_S16_NE     + SA_PCM_FORMAT_S32_NE    ] = format_s16_to_s32,     /* done */ +        [_SA_PCM_FORMAT_MAX * SA_PCM_FORMAT_S16_NE     + SA_PCM_FORMAT_FLOAT32_NE] = format_s16_to_f32,     /* done */ +  +        [_SA_PCM_FORMAT_MAX * SA_PCM_FORMAT_S24_NE     + SA_PCM_FORMAT_S32_NE    ] = format_s24_to_s32,     /* done, no liboil */ +        [_SA_PCM_FORMAT_MAX * SA_PCM_FORMAT_S24_NE     + SA_PCM_FORMAT_FLOAT32_NE] = format_s24_to_f32,     /* done, no liboil */ +         +        [_SA_PCM_FORMAT_MAX * SA_PCM_FORMAT_S32_NE     + SA_PCM_FORMAT_U8        ] = format_s32_to_u8,      /* done, no liboil */ +        [_SA_PCM_FORMAT_MAX * SA_PCM_FORMAT_S32_NE     + SA_PCM_FORMAT_ULAW      ] = format_s32_to_ulaw,    /* done, no liboil */ +        [_SA_PCM_FORMAT_MAX * SA_PCM_FORMAT_S32_NE     + SA_PCM_FORMAT_ALAW      ] = format_s32_to_alaw,    /* done, no liboil */ +        [_SA_PCM_FORMAT_MAX * SA_PCM_FORMAT_S32_NE     + SA_PCM_FORMAT_S16_NE    ] = format_s32_to_s16,     /* done, no liboil */ +        [_SA_PCM_FORMAT_MAX * SA_PCM_FORMAT_S32_NE     + SA_PCM_FORMAT_S24_NE    ] = format_s32_to_s24,     /* done, no liboil */ +        [_SA_PCM_FORMAT_MAX * SA_PCM_FORMAT_S32_NE     + SA_PCM_FORMAT_FLOAT32_NE] = format_s32_to_f32,     /* done, but suboptimal */ +         +        [_SA_PCM_FORMAT_MAX * SA_PCM_FORMAT_FLOAT32_NE + SA_PCM_FORMAT_U8        ] = format_f32_to_u8,      /* done */ +        [_SA_PCM_FORMAT_MAX * SA_PCM_FORMAT_FLOAT32_NE + SA_PCM_FORMAT_ULAW      ] = format_f32_to_ulaw,    /* done, no liboil */ +        [_SA_PCM_FORMAT_MAX * SA_PCM_FORMAT_FLOAT32_NE + SA_PCM_FORMAT_ALAW      ] = format_f32_to_alaw,    /* done, no liboil */ +        [_SA_PCM_FORMAT_MAX * SA_PCM_FORMAT_FLOAT32_NE + SA_PCM_FORMAT_S16_NE    ] = format_f32_to_s16,     /* done */ +        [_SA_PCM_FORMAT_MAX * SA_PCM_FORMAT_FLOAT32_NE + SA_PCM_FORMAT_S24_NE    ] = format_f32_to_s24,     /* done, no liboil */ +        [_SA_PCM_FORMAT_MAX * SA_PCM_FORMAT_FLOAT32_NE + SA_PCM_FORMAT_S32_NE    ] = format_f32_to_s32,     /* done, but suboptimal */ +    }; + +    sa_assert(from < _SA_PCM_FORMAT_MAX); +    sa_assert(to < _SA_PCM_FORMAT_MAX); +     +    return funcs[from * _SA_PCM_FORMAT_MAX + to]; +} diff --git a/src/format.h b/src/format.h new file mode 100644 index 0000000..91caf25 --- /dev/null +++ b/src/format.h @@ -0,0 +1,13 @@ +#ifndef foosydneyformathfoo +#define foosydneyformathfoo + +#include <sys/types.h> + +#include "sydney.h" +#include "bbuffer.h" + +typedef int (*sa_format_func_t) (sa_bbuffer_t *b, void *dst, size_t dstr, const void *src, size_t sstr, size_t bytes); + +sa_format_func_t sa_get_format_func(sa_pcm_format_t from, sa_pcm_format_t to); + +#endif diff --git a/src/g711.c b/src/g711.c new file mode 100644 index 0000000..df76ac7 --- /dev/null +++ b/src/g711.c @@ -0,0 +1,2531 @@ +/*
 + * This source code is a product of Sun Microsystems, Inc. and is provided
 + * for unrestricted use.  Users may copy or modify this source code without
 + * charge.
 + *
 + * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
 + * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
 + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
 + *
 + * Sun source code is provided with no support and without any obligation on
 + * the part of Sun Microsystems, Inc. to assist in its use, correction,
 + * modification or enhancement.
 + *
 + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
 + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
 + * OR ANY PART THEREOF.
 + *
 + * In no event will Sun Microsystems, Inc. be liable for any lost revenue
 + * or profits or other special, indirect and consequential damages, even if
 + * Sun has been advised of the possibility of such damages.
 + *
 + * Sun Microsystems, Inc.
 + * 2550 Garcia Avenue
 + * Mountain View, California  94043
 + */
 +
 +/*
 + * g711.c
 + *
 + * u-law, A-law and linear PCM conversions.
 + */
 +
 +/*
 + * December 30, 1994:
 + * Functions linear2alaw, linear2ulaw have been updated to correctly
 + * convert unquantized 16 bit values.
 + * Tables for direct u- to A-law and A- to u-law conversions have been
 + * corrected.
 + * Borge Lindberg, Center for PersonKommunikation, Aalborg University.
 + * bli@cpk.auc.dk
 + *
 + */
 +
 +#include "g711.h"
 +
 +#define	SIGN_BIT	(0x80)		/* Sign bit for a A-law byte. */
 +#define	QUANT_MASK	(0xf)		/* Quantization field mask. */
 +#define	NSEGS		(8)		/* Number of A-law segments. */
 +#define	SEG_SHIFT	(4)		/* Left shift for segment number. */
 +#define	SEG_MASK	(0x70)		/* Segment field mask. */
 +
 +#if !defined(FAST_ALAW_CONVERSION) || !defined(FAST_ULAW_CONVERSION)
 +static int16_t seg_aend[8] = {0x1F, 0x3F, 0x7F, 0xFF,
 +			      0x1FF, 0x3FF, 0x7FF, 0xFFF};
 +static int16_t seg_uend[8] = {0x3F, 0x7F, 0xFF, 0x1FF,
 +			      0x3FF, 0x7FF, 0xFFF, 0x1FFF};
 +
 +static int16_t search(
 +	int16_t	val,
 +	int16_t *table,
 +	int size)
 +{
 +	int i;
 +
 +	for (i = 0; i < size; i++) {
 +		if (val <= *table++)
 +			return (i);
 +	}
 +	return (size);
 +}
 +#endif /* !FAST_*_CONVERSION */
 +
 +#ifndef FAST_ALAW_CONVERSION
 +/*
 + * linear2alaw() accepts an 13-bit signed integer and encodes it as A-law data
 + * stored in a unsigned char.  This function should only be called with
 + * the data shifted such that it only contains information in the lower
 + * 13-bits.
 + *
 + *		Linear Input Code	Compressed Code
 + *	------------------------	---------------
 + *	0000000wxyza			000wxyz
 + *	0000001wxyza			001wxyz
 + *	000001wxyzab			010wxyz
 + *	00001wxyzabc			011wxyz
 + *	0001wxyzabcd			100wxyz
 + *	001wxyzabcde			101wxyz
 + *	01wxyzabcdef			110wxyz
 + *	1wxyzabcdefg			111wxyz
 + *
 + * For further information see John C. Bellamy's Digital Telephony, 1982,
 + * John Wiley & Sons, pps 98-111 and 472-476.
 + */
 +unsigned char sa_13linear2alaw(
 +	int16_t		pcm_val)	/* 2's complement (13-bit range) */
 +{
 +	int16_t		mask;
 +	short		seg;
 +	unsigned char	aval;
 +
 +	/* Have calling software do it since its already doing a shift
 +	 * from 32-bits down to 16-bits.
 +	 */
 +	/* pcm_val = pcm_val >> 3; */
 +
 +	/* A-law using even bit inversion */
 +	if (pcm_val >= 0) {
 +		mask = 0xD5;		/* sign (7th) bit = 1 */
 +	} else {
 +		mask = 0x55;		/* sign bit = 0 */
 +		pcm_val = -pcm_val - 1;
 +	}
 +
 +	/* Convert the scaled magnitude to segment number. */
 +	seg = search(pcm_val, seg_aend, 8);
 +
 +	/* Combine the sign, segment, and quantization bits. */
 +
 +	if (seg >= 8)		/* out of range, return maximum value. */
 +		return (unsigned char) (0x7F ^ mask);
 +	else {
 +		aval = (unsigned char) seg << SEG_SHIFT;
 +		if (seg < 2)
 +			aval |= (pcm_val >> 1) & QUANT_MASK;
 +		else
 +			aval |= (pcm_val >> seg) & QUANT_MASK;
 +		return (aval ^ mask);
 +	}
 +}
 +
 +/*
 + * alaw2linear() - Convert an A-law value to 16-bit signed linear PCM
 + *
 + */
 +int16_t sa_alaw2linear16(
 +	unsigned char	a_val)
 +{
 +	int16_t t;
 +	int16_t seg;
 +
 +	a_val ^= 0x55;
 +
 +	t = (a_val & QUANT_MASK) << 4;
 +	seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT;
 +	switch (seg) {
 +	case 0:
 +		t += 8;
 +		break;
 +	case 1:
 +		t += 0x108;
 +		break;
 +	default:
 +		t += 0x108;
 +		t <<= seg - 1;
 +	}
 +	return ((a_val & SIGN_BIT) ? t : -t);
 +}
 +#endif /* !FAST_ALAW_CONVERSION */
 +
 +#define	BIAS		(0x84)		/* Bias for linear code. */
 +#define CLIP            8159
 +
 +#ifndef FAST_ULAW_CONVERSION
 +/*
 + * linear2ulaw() accepts a 14-bit signed integer and encodes it as u-law data
 + * stored in a unsigned char.  This function should only be called with
 + * the data shifted such that it only contains information in the lower
 + * 14-bits.
 + *
 + * In order to simplify the encoding process, the original linear magnitude
 + * is biased by adding 33 which shifts the encoding range from (0 - 8158) to
 + * (33 - 8191). The result can be seen in the following encoding table:
 + *
 + *	Biased Linear Input Code	Compressed Code
 + *	------------------------	---------------
 + *	00000001wxyza			000wxyz
 + *	0000001wxyzab			001wxyz
 + *	000001wxyzabc			010wxyz
 + *	00001wxyzabcd			011wxyz
 + *	0001wxyzabcde			100wxyz
 + *	001wxyzabcdef			101wxyz
 + *	01wxyzabcdefg			110wxyz
 + *	1wxyzabcdefgh			111wxyz
 + *
 + * Each biased linear code has a leading 1 which identifies the segment
 + * number. The value of the segment number is equal to 7 minus the number
 + * of leading 0's. The quantization interval is directly available as the
 + * four bits wxyz.  * The trailing bits (a - h) are ignored.
 + *
 + * Ordinarily the complement of the resulting code word is used for
 + * transmission, and so the code word is complemented before it is returned.
 + *
 + * For further information see John C. Bellamy's Digital Telephony, 1982,
 + * John Wiley & Sons, pps 98-111 and 472-476.
 + */
 +unsigned char sa_14linear2ulaw(
 +	int16_t		pcm_val)	/* 2's complement (14-bit range) */
 +{
 +	int16_t		mask;
 +	int16_t		seg;
 +	unsigned char	uval;
 +
 +	/* Have calling software do it since its already doing a shift
 +	 * from 32-bits down to 16-bits.
 +	 */
 +	/* pcm_val = pcm_val >> 2; */
 +
 +	/* u-law inverts all bits */
 +	/* Get the sign and the magnitude of the value. */
 +	if (pcm_val < 0) {
 +		pcm_val = -pcm_val;
 +		mask = 0x7F;
 +	} else {
 +		mask = 0xFF;
 +	}
 +        if ( pcm_val > CLIP ) pcm_val = CLIP;		/* clip the magnitude */
 +	pcm_val += (BIAS >> 2);
 +
 +	/* Convert the scaled magnitude to segment number. */
 +	seg = search(pcm_val, seg_uend, 8);
 +
 +	/*
 +	 * Combine the sign, segment, quantization bits;
 +	 * and complement the code word.
 +	 */
 +	if (seg >= 8)		/* out of range, return maximum value. */
 +		return (unsigned char) (0x7F ^ mask);
 +	else {
 +		uval = (unsigned char) (seg << 4) | ((pcm_val >> (seg + 1)) & 0xF);
 +		return (uval ^ mask);
 +	}
 +
 +}
 +
 +/*
 + * ulaw2linear() - Convert a u-law value to 16-bit linear PCM
 + *
 + * First, a biased linear code is derived from the code word. An unbiased
 + * output can then be obtained by subtracting 33 from the biased code.
 + *
 + * Note that this function expects to be passed the complement of the
 + * original code word. This is in keeping with ISDN conventions.
 + */
 +int16_t sa_ulaw2linear16(
 +	unsigned char	u_val)
 +{
 +	int16_t		t;
 +
 +	/* Complement to obtain normal u-law value. */
 +	u_val = ~u_val;
 +
 +	/*
 +	 * Extract and bias the quantization bits. Then
 +	 * shift up by the segment number and subtract out the bias.
 +	 */
 +	t = ((u_val & QUANT_MASK) << 3) + BIAS;
 +	t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT;
 +
 +	return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS));
 +}
 +#endif /* !FAST_ULAW_CONVERSION */
 +
 +#ifdef FAST_ALAW_CONVERSION
 +
 +int16_t _sa_alaw2linear16[256] = {
 +     -5504,   -5248,   -6016,   -5760,   -4480,   -4224,   -4992,
 +     -4736,   -7552,   -7296,   -8064,   -7808,   -6528,   -6272,
 +     -7040,   -6784,   -2752,   -2624,   -3008,   -2880,   -2240,
 +     -2112,   -2496,   -2368,   -3776,   -3648,   -4032,   -3904,
 +     -3264,   -3136,   -3520,   -3392,  -22016,  -20992,  -24064,
 +    -23040,  -17920,  -16896,  -19968,  -18944,  -30208,  -29184,
 +    -32256,  -31232,  -26112,  -25088,  -28160,  -27136,  -11008,
 +    -10496,  -12032,  -11520,   -8960,   -8448,   -9984,   -9472,
 +    -15104,  -14592,  -16128,  -15616,  -13056,  -12544,  -14080,
 +    -13568,    -344,    -328,    -376,    -360,    -280,    -264,
 +      -312,    -296,    -472,    -456,    -504,    -488,    -408,
 +      -392,    -440,    -424,     -88,     -72,    -120,    -104,
 +       -24,      -8,     -56,     -40,    -216,    -200,    -248,
 +      -232,    -152,    -136,    -184,    -168,   -1376,   -1312,
 +     -1504,   -1440,   -1120,   -1056,   -1248,   -1184,   -1888,
 +     -1824,   -2016,   -1952,   -1632,   -1568,   -1760,   -1696,
 +      -688,    -656,    -752,    -720,    -560,    -528,    -624,
 +      -592,    -944,    -912,   -1008,    -976,    -816,    -784,
 +      -880,    -848,    5504,    5248,    6016,    5760,    4480,
 +      4224,    4992,    4736,    7552,    7296,    8064,    7808,
 +      6528,    6272,    7040,    6784,    2752,    2624,    3008,
 +      2880,    2240,    2112,    2496,    2368,    3776,    3648,
 +      4032,    3904,    3264,    3136,    3520,    3392,   22016,
 +     20992,   24064,   23040,   17920,   16896,   19968,   18944,
 +     30208,   29184,   32256,   31232,   26112,   25088,   28160,
 +     27136,   11008,   10496,   12032,   11520,    8960,    8448,
 +      9984,    9472,   15104,   14592,   16128,   15616,   13056,
 +     12544,   14080,   13568,     344,     328,     376,     360,
 +       280,     264,     312,     296,     472,     456,     504,
 +       488,     408,     392,     440,     424,      88,      72,
 +       120,     104,      24,       8,      56,      40,     216,
 +       200,     248,     232,     152,     136,     184,     168,
 +      1376,    1312,    1504,    1440,    1120,    1056,    1248,
 +      1184,    1888,    1824,    2016,    1952,    1632,    1568,
 +      1760,    1696,     688,     656,     752,     720,     560,
 +       528,     624,     592,     944,     912,    1008,     976,
 +       816,     784,     880,     848
 +};
 +
 +uint8_t _sa_13linear2alaw[0x2000] = {
 +   0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
 +   0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
 +   0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
 +   0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
 +   0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
 +   0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
 +   0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
 +   0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
 +   0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
 +   0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
 +   0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b,
 +   0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
 +   0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
 +   0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
 +   0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
 +   0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
 +   0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
 +   0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
 +   0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
 +   0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
 +   0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
 +   0x2b, 0x2b, 0x2b, 0x2b, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
 +   0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
 +   0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
 +   0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
 +   0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
 +   0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
 +   0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
 +   0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
 +   0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
 +   0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
 +   0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
 +   0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
 +   0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
 +   0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
 +   0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
 +   0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
 +   0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
 +   0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
 +   0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
 +   0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
 +   0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
 +   0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x2e, 0x2e, 0x2e, 0x2e,
 +   0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
 +   0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
 +   0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
 +   0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
 +   0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
 +   0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
 +   0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
 +   0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
 +   0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
 +   0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
 +   0x2e, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
 +   0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
 +   0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
 +   0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
 +   0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
 +   0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
 +   0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
 +   0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
 +   0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
 +   0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
 +   0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
 +   0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
 +   0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
 +   0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
 +   0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
 +   0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
 +   0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
 +   0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
 +   0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
 +   0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
 +   0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
 +   0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2d, 0x2d, 0x2d, 0x2d,
 +   0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
 +   0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
 +   0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
 +   0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
 +   0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
 +   0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
 +   0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
 +   0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
 +   0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
 +   0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
 +   0x2d, 0x2d, 0x2d, 0x2d, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
 +   0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
 +   0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
 +   0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
 +   0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
 +   0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
 +   0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
 +   0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
 +   0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
 +   0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
 +   0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
 +   0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
 +   0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
 +   0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
 +   0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
 +   0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
 +   0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
 +   0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
 +   0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
 +   0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
 +   0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
 +   0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x20, 0x20, 0x20, 0x20,
 +   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 +   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 +   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 +   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 +   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 +   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 +   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 +   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 +   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 +   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 +   0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
 +   0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
 +   0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
 +   0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
 +   0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
 +   0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
 +   0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
 +   0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
 +   0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
 +   0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
 +   0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
 +   0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
 +   0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
 +   0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
 +   0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
 +   0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
 +   0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
 +   0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
 +   0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
 +   0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
 +   0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
 +   0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x27, 0x27, 0x27, 0x27,
 +   0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
 +   0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
 +   0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
 +   0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
 +   0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
 +   0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
 +   0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
 +   0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
 +   0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
 +   0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
 +   0x27, 0x27, 0x27, 0x27, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
 +   0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
 +   0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
 +   0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
 +   0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
 +   0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
 +   0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
 +   0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
 +   0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
 +   0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
 +   0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
 +   0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
 +   0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
 +   0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
 +   0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
 +   0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
 +   0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
 +   0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
 +   0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
 +   0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
 +   0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
 +   0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x3a, 0x3a, 0x3a, 0x3a,
 +   0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a,
 +   0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a,
 +   0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a,
 +   0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a,
 +   0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a,
 +   0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
 +   0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
 +   0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
 +   0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
 +   0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
 +   0x3b, 0x3b, 0x3b, 0x3b, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
 +   0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
 +   0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
 +   0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
 +   0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
 +   0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x39, 0x39, 0x39, 0x39,
 +   0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
 +   0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
 +   0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
 +   0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
 +   0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
 +   0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e,
 +   0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e,
 +   0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e,
 +   0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e,
 +   0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e,
 +   0x3e, 0x3e, 0x3e, 0x3e, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
 +   0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
 +   0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
 +   0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
 +   0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
 +   0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3c, 0x3c, 0x3c, 0x3c,
 +   0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
 +   0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
 +   0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
 +   0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
 +   0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
 +   0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d,
 +   0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d,
 +   0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d,
 +   0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d,
 +   0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d,
 +   0x3d, 0x3d, 0x3d, 0x3d, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
 +   0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
 +   0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
 +   0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
 +   0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
 +   0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x33, 0x33, 0x33, 0x33,
 +   0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
 +   0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
 +   0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
 +   0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
 +   0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
 +   0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
 +   0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
 +   0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
 +   0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
 +   0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
 +   0x30, 0x30, 0x30, 0x30, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
 +   0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
 +   0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
 +   0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
 +   0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
 +   0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x36, 0x36, 0x36, 0x36,
 +   0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
 +   0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
 +   0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
 +   0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
 +   0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
 +   0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37,
 +   0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37,
 +   0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37,
 +   0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37,
 +   0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37,
 +   0x37, 0x37, 0x37, 0x37, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34,
 +   0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34,
 +   0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34,
 +   0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34,
 +   0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34,
 +   0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x35, 0x35, 0x35, 0x35,
 +   0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
 +   0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
 +   0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
 +   0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
 +   0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
 +   0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
 +   0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
 +   0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0b, 0x0b,
 +   0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
 +   0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
 +   0x0b, 0x0b, 0x0b, 0x0b, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
 +   0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
 +   0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
 +   0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
 +   0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
 +   0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0e, 0x0e, 0x0e, 0x0e,
 +   0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
 +   0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
 +   0x0e, 0x0e, 0x0e, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
 +   0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
 +   0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
 +   0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
 +   0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
 +   0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0d, 0x0d, 0x0d, 0x0d,
 +   0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
 +   0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
 +   0x0d, 0x0d, 0x0d, 0x0d, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
 +   0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
 +   0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
 +   0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
 +   0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
 +   0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00,
 +   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 +   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 +   0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
 +   0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
 +   0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
 +   0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
 +   0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
 +   0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07,
 +   0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
 +   0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
 +   0x07, 0x07, 0x07, 0x07, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
 +   0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
 +   0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
 +   0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
 +   0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
 +   0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x1a, 0x1a, 0x1a, 0x1a,
 +   0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
 +   0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b,
 +   0x1b, 0x1b, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
 +   0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x19, 0x19, 0x19, 0x19,
 +   0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
 +   0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
 +   0x1e, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
 +   0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1c, 0x1c, 0x1c, 0x1c,
 +   0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
 +   0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
 +   0x1d, 0x1d, 0x1d, 0x1d, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
 +   0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13,
 +   0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
 +   0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
 +   0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
 +   0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x16, 0x16, 0x16, 0x16,
 +   0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
 +   0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
 +   0x17, 0x17, 0x17, 0x17, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
 +   0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15,
 +   0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
 +   0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6b, 0x6b, 0x6b, 0x6b,
 +   0x6b, 0x6b, 0x6b, 0x6b, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68,
 +   0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x6e, 0x6e, 0x6e, 0x6e,
 +   0x6e, 0x6e, 0x6e, 0x6e, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f,
 +   0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6d, 0x6d, 0x6d, 0x6d,
 +   0x6d, 0x6d, 0x6d, 0x6d, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62,
 +   0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x60, 0x60, 0x60, 0x60,
 +   0x60, 0x60, 0x60, 0x60, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
 +   0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x67, 0x67, 0x67, 0x67,
 +   0x67, 0x67, 0x67, 0x67, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64,
 +   0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x7a, 0x7a, 0x7a, 0x7a,
 +   0x7b, 0x7b, 0x7b, 0x7b, 0x78, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79, 0x79,
 +   0x7e, 0x7e, 0x7e, 0x7e, 0x7f, 0x7f, 0x7f, 0x7f, 0x7c, 0x7c, 0x7c, 0x7c,
 +   0x7d, 0x7d, 0x7d, 0x7d, 0x72, 0x72, 0x72, 0x72, 0x73, 0x73, 0x73, 0x73,
 +   0x70, 0x70, 0x70, 0x70, 0x71, 0x71, 0x71, 0x71, 0x76, 0x76, 0x76, 0x76,
 +   0x77, 0x77, 0x77, 0x77, 0x74, 0x74, 0x74, 0x74, 0x75, 0x75, 0x75, 0x75,
 +   0x4a, 0x4a, 0x4b, 0x4b, 0x48, 0x48, 0x49, 0x49, 0x4e, 0x4e, 0x4f, 0x4f,
 +   0x4c, 0x4c, 0x4d, 0x4d, 0x42, 0x42, 0x43, 0x43, 0x40, 0x40, 0x41, 0x41,
 +   0x46, 0x46, 0x47, 0x47, 0x44, 0x44, 0x45, 0x45, 0x5a, 0x5a, 0x5b, 0x5b,
 +   0x58, 0x58, 0x59, 0x59, 0x5e, 0x5e, 0x5f, 0x5f, 0x5c, 0x5c, 0x5d, 0x5d,
 +   0x52, 0x52, 0x53, 0x53, 0x50, 0x50, 0x51, 0x51, 0x56, 0x56, 0x57, 0x57,
 +   0x54, 0x54, 0x55, 0x55, 0xd5, 0xd5, 0xd4, 0xd4, 0xd7, 0xd7, 0xd6, 0xd6,
 +   0xd1, 0xd1, 0xd0, 0xd0, 0xd3, 0xd3, 0xd2, 0xd2, 0xdd, 0xdd, 0xdc, 0xdc,
 +   0xdf, 0xdf, 0xde, 0xde, 0xd9, 0xd9, 0xd8, 0xd8, 0xdb, 0xdb, 0xda, 0xda,
 +   0xc5, 0xc5, 0xc4, 0xc4, 0xc7, 0xc7, 0xc6, 0xc6, 0xc1, 0xc1, 0xc0, 0xc0,
 +   0xc3, 0xc3, 0xc2, 0xc2, 0xcd, 0xcd, 0xcc, 0xcc, 0xcf, 0xcf, 0xce, 0xce,
 +   0xc9, 0xc9, 0xc8, 0xc8, 0xcb, 0xcb, 0xca, 0xca, 0xf5, 0xf5, 0xf5, 0xf5,
 +   0xf4, 0xf4, 0xf4, 0xf4, 0xf7, 0xf7, 0xf7, 0xf7, 0xf6, 0xf6, 0xf6, 0xf6,
 +   0xf1, 0xf1, 0xf1, 0xf1, 0xf0, 0xf0, 0xf0, 0xf0, 0xf3, 0xf3, 0xf3, 0xf3,
 +   0xf2, 0xf2, 0xf2, 0xf2, 0xfd, 0xfd, 0xfd, 0xfd, 0xfc, 0xfc, 0xfc, 0xfc,
 +   0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfe, 0xfe, 0xf9, 0xf9, 0xf9, 0xf9,
 +   0xf8, 0xf8, 0xf8, 0xf8, 0xfb, 0xfb, 0xfb, 0xfb, 0xfa, 0xfa, 0xfa, 0xfa,
 +   0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe4, 0xe4, 0xe4, 0xe4,
 +   0xe4, 0xe4, 0xe4, 0xe4, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7,
 +   0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe1, 0xe1, 0xe1, 0xe1,
 +   0xe1, 0xe1, 0xe1, 0xe1, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0,
 +   0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe2, 0xe2, 0xe2, 0xe2,
 +   0xe2, 0xe2, 0xe2, 0xe2, 0xed, 0xed, 0xed, 0xed, 0xed, 0xed, 0xed, 0xed,
 +   0xec, 0xec, 0xec, 0xec, 0xec, 0xec, 0xec, 0xec, 0xef, 0xef, 0xef, 0xef,
 +   0xef, 0xef, 0xef, 0xef, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
 +   0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe8, 0xe8, 0xe8, 0xe8,
 +   0xe8, 0xe8, 0xe8, 0xe8, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
 +   0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0x95, 0x95, 0x95, 0x95,
 +   0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
 +   0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
 +   0x94, 0x94, 0x94, 0x94, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
 +   0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x96, 0x96, 0x96, 0x96,
 +   0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
 +   0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
 +   0x91, 0x91, 0x91, 0x91, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
 +   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x93, 0x93, 0x93, 0x93,
 +   0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
 +   0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
 +   0x92, 0x92, 0x92, 0x92, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
 +   0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9c, 0x9c, 0x9c, 0x9c,
 +   0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
 +   0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
 +   0x9f, 0x9f, 0x9f, 0x9f, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
 +   0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x99, 0x99, 0x99, 0x99,
 +   0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
 +   0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
 +   0x98, 0x98, 0x98, 0x98, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
 +   0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9a, 0x9a, 0x9a, 0x9a,
 +   0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
 +   0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
 +   0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
 +   0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x84, 0x84, 0x84, 0x84,
 +   0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
 +   0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
 +   0x84, 0x84, 0x84, 0x84, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
 +   0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
 +   0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
 +   0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
 +   0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
 +   0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x81, 0x81, 0x81, 0x81,
 +   0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
 +   0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
 +   0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
 +   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
 +   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
 +   0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
 +   0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
 +   0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x82, 0x82, 0x82, 0x82,
 +   0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
 +   0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
 +   0x82, 0x82, 0x82, 0x82, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
 +   0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
 +   0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
 +   0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
 +   0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
 +   0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8f, 0x8f, 0x8f, 0x8f,
 +   0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
 +   0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
 +   0x8f, 0x8f, 0x8f, 0x8f, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
 +   0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
 +   0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
 +   0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
 +   0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
 +   0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x88, 0x88, 0x88, 0x88,
 +   0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
 +   0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
 +   0x88, 0x88, 0x88, 0x88, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
 +   0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
 +   0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
 +   0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
 +   0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
 +   0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0xb5, 0xb5, 0xb5, 0xb5,
 +   0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5,
 +   0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5,
 +   0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5,
 +   0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5,
 +   0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5,
 +   0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
 +   0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
 +   0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
 +   0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
 +   0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
 +   0xb4, 0xb4, 0xb4, 0xb4, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7,
 +   0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7,
 +   0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7,
 +   0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7,
 +   0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7,
 +   0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb6, 0xb6, 0xb6, 0xb6,
 +   0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6,
 +   0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6,
 +   0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6,
 +   0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6,
 +   0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6,
 +   0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1,
 +   0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1,
 +   0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1,
 +   0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1,
 +   0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1,
 +   0xb1, 0xb1, 0xb1, 0xb1, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0,
 +   0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0,
 +   0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0,
 +   0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0,
 +   0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0,
 +   0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb3, 0xb3, 0xb3, 0xb3,
 +   0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3,
 +   0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3,
 +   0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3,
 +   0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3,
 +   0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3,
 +   0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2,
 +   0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2,
 +   0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2,
 +   0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2,
 +   0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2,
 +   0xb2, 0xb2, 0xb2, 0xb2, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd,
 +   0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd,
 +   0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd,
 +   0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd,
 +   0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd,
 +   0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbc, 0xbc, 0xbc, 0xbc,
 +   0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc,
 +   0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc,
 +   0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc,
 +   0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc,
 +   0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc,
 +   0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
 +   0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
 +   0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
 +   0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
 +   0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
 +   0xbf, 0xbf, 0xbf, 0xbf, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
 +   0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
 +   0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
 +   0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
 +   0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
 +   0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xb9, 0xb9, 0xb9, 0xb9,
 +   0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9,
 +   0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9,
 +   0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9,
 +   0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9,
 +   0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9,
 +   0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8,
 +   0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8,
 +   0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8,
 +   0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8,
 +   0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8,
 +   0xb8, 0xb8, 0xb8, 0xb8, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
 +   0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
 +   0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
 +   0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
 +   0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
 +   0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xba, 0xba, 0xba, 0xba,
 +   0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba,
 +   0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba,
 +   0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba,
 +   0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba,
 +   0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba,
 +   0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
 +   0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
 +   0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
 +   0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
 +   0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
 +   0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
 +   0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
 +   0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
 +   0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
 +   0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
 +   0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa4, 0xa4, 0xa4, 0xa4,
 +   0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
 +   0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
 +   0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
 +   0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
 +   0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
 +   0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
 +   0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
 +   0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
 +   0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
 +   0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
 +   0xa4, 0xa4, 0xa4, 0xa4, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
 +   0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
 +   0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
 +   0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
 +   0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
 +   0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
 +   0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
 +   0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
 +   0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
 +   0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
 +   0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
 +   0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
 +   0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
 +   0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
 +   0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
 +   0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
 +   0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
 +   0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
 +   0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
 +   0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
 +   0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
 +   0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa1, 0xa1, 0xa1, 0xa1,
 +   0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
 +   0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
 +   0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
 +   0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
 +   0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
 +   0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
 +   0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
 +   0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
 +   0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
 +   0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
 +   0xa1, 0xa1, 0xa1, 0xa1, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
 +   0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
 +   0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
 +   0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
 +   0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
 +   0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
 +   0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
 +   0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
 +   0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
 +   0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
 +   0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
 +   0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
 +   0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
 +   0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
 +   0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
 +   0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
 +   0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
 +   0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
 +   0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
 +   0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
 +   0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
 +   0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa2, 0xa2, 0xa2, 0xa2,
 +   0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
 +   0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
 +   0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
 +   0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
 +   0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
 +   0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
 +   0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
 +   0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
 +   0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
 +   0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
 +   0xa2, 0xa2, 0xa2, 0xa2, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
 +   0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
 +   0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
 +   0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
 +   0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
 +   0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
 +   0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
 +   0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
 +   0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
 +   0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
 +   0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
 +   0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
 +   0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
 +   0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
 +   0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
 +   0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
 +   0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
 +   0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
 +   0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
 +   0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
 +   0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
 +   0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xaf, 0xaf, 0xaf, 0xaf,
 +   0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
 +   0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
 +   0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
 +   0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
 +   0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
 +   0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
 +   0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
 +   0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
 +   0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
 +   0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
 +   0xaf, 0xaf, 0xaf, 0xaf, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
 +   0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
 +   0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
 +   0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
 +   0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
 +   0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
 +   0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
 +   0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
 +   0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
 +   0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
 +   0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
 +   0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
 +   0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
 +   0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
 +   0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
 +   0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
 +   0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
 +   0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
 +   0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
 +   0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
 +   0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
 +   0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa8, 0xa8, 0xa8, 0xa8,
 +   0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
 +   0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
 +   0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
 +   0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
 +   0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
 +   0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
 +   0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
 +   0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
 +   0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
 +   0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
 +   0xa8, 0xa8, 0xa8, 0xa8, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
 +   0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
 +   0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
 +   0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
 +   0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
 +   0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
 +   0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
 +   0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
 +   0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
 +   0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
 +   0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
 +   0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
 +   0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
 +   0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
 +   0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
 +   0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
 +   0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
 +   0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
 +   0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
 +   0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
 +   0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
 +   0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa
 +};
 +
 +#endif /* FAST_ALAW_CONVERSION */
 +
 +#ifdef FAST_ULAW_CONVERSION
 +
 +int16_t _sa_ulaw2linear16[256] = {
 +    -32124,  -31100,  -30076,  -29052,  -28028,  -27004,  -25980,
 +    -24956,  -23932,  -22908,  -21884,  -20860,  -19836,  -18812,
 +    -17788,  -16764,  -15996,  -15484,  -14972,  -14460,  -13948,
 +    -13436,  -12924,  -12412,  -11900,  -11388,  -10876,  -10364,
 +     -9852,   -9340,   -8828,   -8316,   -7932,   -7676,   -7420,
 +     -7164,   -6908,   -6652,   -6396,   -6140,   -5884,   -5628,
 +     -5372,   -5116,   -4860,   -4604,   -4348,   -4092,   -3900,
 +     -3772,   -3644,   -3516,   -3388,   -3260,   -3132,   -3004,
 +     -2876,   -2748,   -2620,   -2492,   -2364,   -2236,   -2108,
 +     -1980,   -1884,   -1820,   -1756,   -1692,   -1628,   -1564,
 +     -1500,   -1436,   -1372,   -1308,   -1244,   -1180,   -1116,
 +     -1052,    -988,    -924,    -876,    -844,    -812,    -780,
 +      -748,    -716,    -684,    -652,    -620,    -588,    -556,
 +      -524,    -492,    -460,    -428,    -396,    -372,    -356,
 +      -340,    -324,    -308,    -292,    -276,    -260,    -244,
 +      -228,    -212,    -196,    -180,    -164,    -148,    -132,
 +      -120,    -112,    -104,     -96,     -88,     -80,     -72,
 +       -64,     -56,     -48,     -40,     -32,     -24,     -16,
 +        -8,       0,   32124,   31100,   30076,   29052,   28028,
 +     27004,   25980,   24956,   23932,   22908,   21884,   20860,
 +     19836,   18812,   17788,   16764,   15996,   15484,   14972,
 +     14460,   13948,   13436,   12924,   12412,   11900,   11388,
 +     10876,   10364,    9852,    9340,    8828,    8316,    7932,
 +      7676,    7420,    7164,    6908,    6652,    6396,    6140,
 +      5884,    5628,    5372,    5116,    4860,    4604,    4348,
 +      4092,    3900,    3772,    3644,    3516,    3388,    3260,
 +      3132,    3004,    2876,    2748,    2620,    2492,    2364,
 +      2236,    2108,    1980,    1884,    1820,    1756,    1692,
 +      1628,    1564,    1500,    1436,    1372,    1308,    1244,
 +      1180,    1116,    1052,     988,     924,     876,     844,
 +       812,     780,     748,     716,     684,     652,     620,
 +       588,     556,     524,     492,     460,     428,     396,
 +       372,     356,     340,     324,     308,     292,     276,
 +       260,     244,     228,     212,     196,     180,     164,
 +       148,     132,     120,     112,     104,      96,      88,
 +        80,      72,      64,      56,      48,      40,      32,
 +        24,      16,       8,       0
 +};
 +
 +uint8_t _sa_14linear2ulaw[0x4000] = {
 +   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 +   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 +   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 +   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 +   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 +   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 +   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 +   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 +   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 +   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 +   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 +   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 +   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 +   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 +   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 +   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 +   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 +   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 +   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 +   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 +   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 +   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 +   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 +   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 +   0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
 +   0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
 +   0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
 +   0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
 +   0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
 +   0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
 +   0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
 +   0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
 +   0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
 +   0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
 +   0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
 +   0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
 +   0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
 +   0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
 +   0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
 +   0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
 +   0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
 +   0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
 +   0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
 +   0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
 +   0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
 +   0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
 +   0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
 +   0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
 +   0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
 +   0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
 +   0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
 +   0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
 +   0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
 +   0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
 +   0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
 +   0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
 +   0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
 +   0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
 +   0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
 +   0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
 +   0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
 +   0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
 +   0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
 +   0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
 +   0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
 +   0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
 +   0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03,
 +   0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
 +   0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
 +   0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
 +   0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
 +   0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
 +   0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
 +   0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
 +   0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
 +   0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
 +   0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
 +   0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
 +   0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
 +   0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
 +   0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
 +   0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
 +   0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
 +   0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
 +   0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
 +   0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
 +   0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
 +   0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
 +   0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
 +   0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
 +   0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
 +   0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
 +   0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
 +   0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
 +   0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
 +   0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
 +   0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
 +   0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
 +   0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
 +   0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
 +   0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
 +   0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
 +   0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
 +   0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
 +   0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
 +   0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
 +   0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
 +   0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
 +   0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
 +   0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
 +   0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
 +   0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
 +   0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
 +   0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
 +   0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
 +   0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
 +   0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
 +   0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
 +   0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
 +   0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
 +   0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
 +   0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
 +   0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
 +   0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
 +   0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
 +   0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
 +   0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
 +   0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
 +   0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
 +   0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
 +   0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06,
 +   0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
 +   0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
 +   0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
 +   0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
 +   0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
 +   0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
 +   0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
 +   0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
 +   0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
 +   0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
 +   0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
 +   0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
 +   0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
 +   0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
 +   0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
 +   0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
 +   0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
 +   0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
 +   0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
 +   0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
 +   0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
 +   0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
 +   0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
 +   0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
 +   0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
 +   0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
 +   0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
 +   0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
 +   0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
 +   0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
 +   0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
 +   0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
 +   0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
 +   0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
 +   0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
 +   0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
 +   0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
 +   0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
 +   0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
 +   0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
 +   0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
 +   0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
 +   0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
 +   0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
 +   0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
 +   0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
 +   0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
 +   0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
 +   0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
 +   0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
 +   0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
 +   0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
 +   0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
 +   0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
 +   0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
 +   0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
 +   0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
 +   0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
 +   0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
 +   0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
 +   0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
 +   0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
 +   0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
 +   0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09,
 +   0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
 +   0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
 +   0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
 +   0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
 +   0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
 +   0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
 +   0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
 +   0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
 +   0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
 +   0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
 +   0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
 +   0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
 +   0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
 +   0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
 +   0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
 +   0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
 +   0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
 +   0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
 +   0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
 +   0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
 +   0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
 +   0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
 +   0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
 +   0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
 +   0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
 +   0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
 +   0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
 +   0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
 +   0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
 +   0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
 +   0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
 +   0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
 +   0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
 +   0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
 +   0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
 +   0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
 +   0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
 +   0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
 +   0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
 +   0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
 +   0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
 +   0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
 +   0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
 +   0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
 +   0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
 +   0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
 +   0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
 +   0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
 +   0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
 +   0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
 +   0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
 +   0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
 +   0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
 +   0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
 +   0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
 +   0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
 +   0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
 +   0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
 +   0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
 +   0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
 +   0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
 +   0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
 +   0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
 +   0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0c, 0x0c,
 +   0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
 +   0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
 +   0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
 +   0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
 +   0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
 +   0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
 +   0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
 +   0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
 +   0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
 +   0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
 +   0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
 +   0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
 +   0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
 +   0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
 +   0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
 +   0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
 +   0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
 +   0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
 +   0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
 +   0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
 +   0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
 +   0x0c, 0x0c, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
 +   0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
 +   0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
 +   0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
 +   0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
 +   0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
 +   0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
 +   0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
 +   0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
 +   0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
 +   0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
 +   0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
 +   0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
 +   0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
 +   0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
 +   0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
 +   0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
 +   0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
 +   0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
 +   0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
 +   0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
 +   0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
 +   0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
 +   0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
 +   0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
 +   0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
 +   0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
 +   0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
 +   0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
 +   0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
 +   0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
 +   0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
 +   0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
 +   0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
 +   0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
 +   0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
 +   0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
 +   0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
 +   0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
 +   0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
 +   0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
 +   0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
 +   0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0f, 0x0f,
 +   0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
 +   0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
 +   0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
 +   0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
 +   0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
 +   0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
 +   0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
 +   0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
 +   0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
 +   0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
 +   0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
 +   0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
 +   0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
 +   0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
 +   0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
 +   0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
 +   0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
 +   0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
 +   0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
 +   0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
 +   0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
 +   0x0f, 0x0f, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
 +   0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
 +   0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
 +   0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
 +   0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
 +   0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
 +   0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
 +   0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
 +   0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
 +   0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
 +   0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11,
 +   0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
 +   0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
 +   0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
 +   0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
 +   0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
 +   0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
 +   0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
 +   0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
 +   0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
 +   0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
 +   0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
 +   0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
 +   0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
 +   0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
 +   0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
 +   0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
 +   0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
 +   0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
 +   0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
 +   0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
 +   0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
 +   0x12, 0x12, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
 +   0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
 +   0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
 +   0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
 +   0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
 +   0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
 +   0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
 +   0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
 +   0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
 +   0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
 +   0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x14, 0x14,
 +   0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
 +   0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
 +   0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
 +   0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
 +   0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
 +   0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
 +   0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
 +   0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
 +   0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
 +   0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
 +   0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
 +   0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
 +   0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
 +   0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
 +   0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
 +   0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
 +   0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
 +   0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
 +   0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
 +   0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
 +   0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
 +   0x15, 0x15, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
 +   0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
 +   0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
 +   0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
 +   0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
 +   0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
 +   0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
 +   0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
 +   0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
 +   0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
 +   0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x17, 0x17,
 +   0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
 +   0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
 +   0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
 +   0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
 +   0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
 +   0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
 +   0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
 +   0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
 +   0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
 +   0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
 +   0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
 +   0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
 +   0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
 +   0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
 +   0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
 +   0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
 +   0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
 +   0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
 +   0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
 +   0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
 +   0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
 +   0x18, 0x18, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
 +   0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
 +   0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
 +   0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
 +   0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
 +   0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
 +   0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
 +   0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
 +   0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
 +   0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
 +   0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x1a, 0x1a,
 +   0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
 +   0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
 +   0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
 +   0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
 +   0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
 +   0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
 +   0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
 +   0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
 +   0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
 +   0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
 +   0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b,
 +   0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b,
 +   0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b,
 +   0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b,
 +   0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b,
 +   0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b,
 +   0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b,
 +   0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b,
 +   0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b,
 +   0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b,
 +   0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b,
 +   0x1b, 0x1b, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
 +   0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
 +   0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
 +   0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
 +   0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
 +   0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
 +   0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
 +   0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
 +   0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
 +   0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
 +   0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1d, 0x1d,
 +   0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
 +   0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
 +   0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
 +   0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
 +   0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
 +   0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
 +   0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
 +   0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
 +   0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
 +   0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
 +   0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
 +   0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
 +   0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
 +   0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
 +   0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
 +   0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
 +   0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
 +   0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
 +   0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
 +   0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
 +   0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
 +   0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
 +   0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
 +   0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
 +   0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
 +   0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
 +   0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
 +   0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
 +   0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
 +   0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
 +   0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
 +   0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x20, 0x20,
 +   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 +   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 +   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 +   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 +   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 +   0x20, 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
 +   0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
 +   0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
 +   0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
 +   0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
 +   0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
 +   0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
 +   0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
 +   0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
 +   0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
 +   0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x23, 0x23,
 +   0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
 +   0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
 +   0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
 +   0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
 +   0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
 +   0x23, 0x23, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
 +   0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
 +   0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
 +   0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
 +   0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
 +   0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
 +   0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
 +   0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
 +   0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
 +   0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
 +   0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x26, 0x26,
 +   0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
 +   0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
 +   0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
 +   0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
 +   0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
 +   0x26, 0x26, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
 +   0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
 +   0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
 +   0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
 +   0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
 +   0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
 +   0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
 +   0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
 +   0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
 +   0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
 +   0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x29, 0x29,
 +   0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
 +   0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
 +   0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
 +   0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
 +   0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
 +   0x29, 0x29, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
 +   0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
 +   0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
 +   0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
 +   0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
 +   0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
 +   0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
 +   0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
 +   0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
 +   0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
 +   0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2c, 0x2c,
 +   0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
 +   0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
 +   0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
 +   0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
 +   0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
 +   0x2c, 0x2c, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
 +   0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
 +   0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
 +   0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
 +   0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
 +   0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
 +   0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
 +   0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
 +   0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
 +   0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
 +   0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f,
 +   0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
 +   0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
 +   0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
 +   0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
 +   0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
 +   0x2f, 0x2f, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
 +   0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
 +   0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x31,
 +   0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
 +   0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
 +   0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
 +   0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
 +   0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
 +   0x32, 0x32, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
 +   0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
 +   0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x34, 0x34,
 +   0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34,
 +   0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34,
 +   0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
 +   0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
 +   0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
 +   0x35, 0x35, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
 +   0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
 +   0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x37,
 +   0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37,
 +   0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37,
 +   0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
 +   0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
 +   0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
 +   0x38, 0x38, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
 +   0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
 +   0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x3a, 0x3a,
 +   0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a,
 +   0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a,
 +   0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
 +   0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
 +   0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
 +   0x3b, 0x3b, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
 +   0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
 +   0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3d, 0x3d,
 +   0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d,
 +   0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d,
 +   0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e,
 +   0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e,
 +   0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e,
 +   0x3e, 0x3e, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
 +   0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
 +   0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x40, 0x40,
 +   0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
 +   0x40, 0x40, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
 +   0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
 +   0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x43, 0x43,
 +   0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43,
 +   0x43, 0x43, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
 +   0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45,
 +   0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x46, 0x46,
 +   0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46,
 +   0x46, 0x46, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
 +   0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
 +   0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x49, 0x49,
 +   0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49,
 +   0x49, 0x49, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a,
 +   0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b,
 +   0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4c, 0x4c,
 +   0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c,
 +   0x4c, 0x4c, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d,
 +   0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e,
 +   0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4f, 0x4f,
 +   0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f,
 +   0x4f, 0x4f, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x51, 0x51,
 +   0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52,
 +   0x52, 0x52, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x54, 0x54,
 +   0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
 +   0x55, 0x55, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x57, 0x57,
 +   0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
 +   0x58, 0x58, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x5a, 0x5a,
 +   0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b,
 +   0x5b, 0x5b, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5d, 0x5d,
 +   0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
 +   0x5e, 0x5e, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x60, 0x60,
 +   0x60, 0x60, 0x61, 0x61, 0x61, 0x61, 0x62, 0x62, 0x62, 0x62, 0x63, 0x63,
 +   0x63, 0x63, 0x64, 0x64, 0x64, 0x64, 0x65, 0x65, 0x65, 0x65, 0x66, 0x66,
 +   0x66, 0x66, 0x67, 0x67, 0x67, 0x67, 0x68, 0x68, 0x68, 0x68, 0x69, 0x69,
 +   0x69, 0x69, 0x6a, 0x6a, 0x6a, 0x6a, 0x6b, 0x6b, 0x6b, 0x6b, 0x6c, 0x6c,
 +   0x6c, 0x6c, 0x6d, 0x6d, 0x6d, 0x6d, 0x6e, 0x6e, 0x6e, 0x6e, 0x6f, 0x6f,
 +   0x6f, 0x6f, 0x70, 0x70, 0x71, 0x71, 0x72, 0x72, 0x73, 0x73, 0x74, 0x74,
 +   0x75, 0x75, 0x76, 0x76, 0x77, 0x77, 0x78, 0x78, 0x79, 0x79, 0x7a, 0x7a,
 +   0x7b, 0x7b, 0x7c, 0x7c, 0x7d, 0x7d, 0x7e, 0x7e, 0xff, 0xfe, 0xfe, 0xfd,
 +   0xfd, 0xfc, 0xfc, 0xfb, 0xfb, 0xfa, 0xfa, 0xf9, 0xf9, 0xf8, 0xf8, 0xf7,
 +   0xf7, 0xf6, 0xf6, 0xf5, 0xf5, 0xf4, 0xf4, 0xf3, 0xf3, 0xf2, 0xf2, 0xf1,
 +   0xf1, 0xf0, 0xf0, 0xef, 0xef, 0xef, 0xef, 0xee, 0xee, 0xee, 0xee, 0xed,
 +   0xed, 0xed, 0xed, 0xec, 0xec, 0xec, 0xec, 0xeb, 0xeb, 0xeb, 0xeb, 0xea,
 +   0xea, 0xea, 0xea, 0xe9, 0xe9, 0xe9, 0xe9, 0xe8, 0xe8, 0xe8, 0xe8, 0xe7,
 +   0xe7, 0xe7, 0xe7, 0xe6, 0xe6, 0xe6, 0xe6, 0xe5, 0xe5, 0xe5, 0xe5, 0xe4,
 +   0xe4, 0xe4, 0xe4, 0xe3, 0xe3, 0xe3, 0xe3, 0xe2, 0xe2, 0xe2, 0xe2, 0xe1,
 +   0xe1, 0xe1, 0xe1, 0xe0, 0xe0, 0xe0, 0xe0, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf,
 +   0xdf, 0xdf, 0xdf, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xdd,
 +   0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc,
 +   0xdc, 0xdc, 0xdc, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xda,
 +   0xda, 0xda, 0xda, 0xda, 0xda, 0xda, 0xda, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9,
 +   0xd9, 0xd9, 0xd9, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0xd7,
 +   0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6,
 +   0xd6, 0xd6, 0xd6, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd4,
 +   0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd3, 0xd3, 0xd3, 0xd3, 0xd3,
 +   0xd3, 0xd3, 0xd3, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd1,
 +   0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0,
 +   0xd0, 0xd0, 0xd0, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf,
 +   0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xce, 0xce, 0xce, 0xce, 0xce,
 +   0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xcd,
 +   0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
 +   0xcd, 0xcd, 0xcd, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
 +   0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb,
 +   0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xca,
 +   0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca,
 +   0xca, 0xca, 0xca, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9,
 +   0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8,
 +   0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc7,
 +   0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7,
 +   0xc7, 0xc7, 0xc7, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
 +   0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5,
 +   0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc4,
 +   0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
 +   0xc4, 0xc4, 0xc4, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3,
 +   0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2,
 +   0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc1,
 +   0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1,
 +   0xc1, 0xc1, 0xc1, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,
 +   0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
 +   0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
 +   0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
 +   0xbf, 0xbf, 0xbf, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
 +   0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
 +   0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbd,
 +   0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd,
 +   0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd,
 +   0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc,
 +   0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc,
 +   0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc,
 +   0xbc, 0xbc, 0xbc, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
 +   0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
 +   0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xba,
 +   0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba,
 +   0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba,
 +   0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9,
 +   0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9,
 +   0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9,
 +   0xb9, 0xb9, 0xb9, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8,
 +   0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8,
 +   0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb7,
 +   0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7,
 +   0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7,
 +   0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6,
 +   0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6,
 +   0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6,
 +   0xb6, 0xb6, 0xb6, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5,
 +   0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5,
 +   0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb4,
 +   0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
 +   0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
 +   0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3,
 +   0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3,
 +   0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3,
 +   0xb3, 0xb3, 0xb3, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2,
 +   0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2,
 +   0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb1,
 +   0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1,
 +   0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1,
 +   0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0,
 +   0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0,
 +   0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0,
 +   0xb0, 0xb0, 0xb0, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
 +   0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
 +   0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
 +   0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
 +   0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
 +   0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xae, 0xae, 0xae, 0xae, 0xae,
 +   0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
 +   0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
 +   0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
 +   0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
 +   0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xad,
 +   0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
 +   0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
 +   0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
 +   0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
 +   0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
 +   0xad, 0xad, 0xad, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
 +   0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
 +   0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
 +   0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
 +   0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
 +   0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xab, 0xab, 0xab, 0xab, 0xab,
 +   0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
 +   0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
 +   0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
 +   0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
 +   0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xaa,
 +   0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
 +   0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
 +   0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
 +   0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
 +   0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
 +   0xaa, 0xaa, 0xaa, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
 +   0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
 +   0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
 +   0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
 +   0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
 +   0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
 +   0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
 +   0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
 +   0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
 +   0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
 +   0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa7,
 +   0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
 +   0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
 +   0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
 +   0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
 +   0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
 +   0xa7, 0xa7, 0xa7, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
 +   0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
 +   0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
 +   0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
 +   0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
 +   0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
 +   0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
 +   0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
 +   0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
 +   0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
 +   0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa4,
 +   0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
 +   0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
 +   0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
 +   0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
 +   0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
 +   0xa4, 0xa4, 0xa4, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
 +   0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
 +   0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
 +   0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
 +   0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
 +   0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
 +   0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
 +   0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
 +   0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
 +   0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
 +   0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa1,
 +   0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
 +   0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
 +   0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
 +   0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
 +   0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
 +   0xa1, 0xa1, 0xa1, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
 +   0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
 +   0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
 +   0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
 +   0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
 +   0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
 +   0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
 +   0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
 +   0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
 +   0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
 +   0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
 +   0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
 +   0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
 +   0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
 +   0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
 +   0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
 +   0x9f, 0x9f, 0x9f, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
 +   0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
 +   0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
 +   0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
 +   0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
 +   0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
 +   0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
 +   0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
 +   0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
 +   0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
 +   0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9d,
 +   0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
 +   0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
 +   0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
 +   0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
 +   0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
 +   0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
 +   0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
 +   0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
 +   0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
 +   0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
 +   0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
 +   0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
 +   0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
 +   0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
 +   0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
 +   0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
 +   0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
 +   0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
 +   0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
 +   0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
 +   0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
 +   0x9c, 0x9c, 0x9c, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
 +   0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
 +   0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
 +   0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
 +   0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
 +   0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
 +   0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
 +   0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
 +   0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
 +   0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
 +   0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9a,
 +   0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
 +   0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
 +   0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
 +   0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
 +   0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
 +   0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
 +   0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
 +   0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
 +   0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
 +   0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
 +   0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x99, 0x99, 0x99, 0x99, 0x99,
 +   0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
 +   0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
 +   0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
 +   0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
 +   0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
 +   0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
 +   0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
 +   0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
 +   0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
 +   0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
 +   0x99, 0x99, 0x99, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
 +   0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
 +   0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
 +   0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
 +   0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
 +   0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
 +   0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
 +   0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
 +   0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
 +   0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
 +   0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x97,
 +   0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
 +   0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
 +   0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
 +   0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
 +   0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
 +   0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
 +   0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
 +   0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
 +   0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
 +   0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
 +   0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x96, 0x96, 0x96, 0x96, 0x96,
 +   0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
 +   0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
 +   0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
 +   0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
 +   0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
 +   0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
 +   0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
 +   0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
 +   0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
 +   0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
 +   0x96, 0x96, 0x96, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
 +   0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
 +   0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
 +   0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
 +   0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
 +   0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
 +   0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
 +   0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
 +   0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
 +   0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
 +   0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x94,
 +   0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
 +   0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
 +   0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
 +   0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
 +   0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
 +   0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
 +   0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
 +   0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
 +   0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
 +   0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
 +   0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x93, 0x93, 0x93, 0x93, 0x93,
 +   0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
 +   0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
 +   0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
 +   0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
 +   0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
 +   0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
 +   0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
 +   0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
 +   0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
 +   0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
 +   0x93, 0x93, 0x93, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
 +   0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
 +   0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
 +   0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
 +   0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
 +   0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
 +   0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
 +   0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
 +   0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
 +   0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
 +   0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x91,
 +   0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
 +   0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
 +   0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
 +   0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
 +   0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
 +   0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
 +   0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
 +   0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
 +   0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
 +   0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
 +   0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x90, 0x90, 0x90, 0x90, 0x90,
 +   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
 +   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
 +   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
 +   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
 +   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
 +   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
 +   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
 +   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
 +   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
 +   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
 +   0x90, 0x90, 0x90, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
 +   0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
 +   0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
 +   0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
 +   0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
 +   0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
 +   0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
 +   0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
 +   0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
 +   0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
 +   0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
 +   0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
 +   0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
 +   0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
 +   0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
 +   0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
 +   0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
 +   0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
 +   0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
 +   0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
 +   0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
 +   0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
 +   0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
 +   0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
 +   0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
 +   0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
 +   0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
 +   0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
 +   0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
 +   0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
 +   0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
 +   0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
 +   0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
 +   0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
 +   0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
 +   0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
 +   0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
 +   0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
 +   0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
 +   0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
 +   0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
 +   0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
 +   0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8d,
 +   0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
 +   0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
 +   0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
 +   0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
 +   0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
 +   0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
 +   0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
 +   0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
 +   0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
 +   0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
 +   0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
 +   0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
 +   0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
 +   0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
 +   0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
 +   0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
 +   0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
 +   0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
 +   0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
 +   0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
 +   0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
 +   0x8d, 0x8d, 0x8d, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
 +   0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
 +   0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
 +   0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
 +   0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
 +   0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
 +   0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
 +   0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
 +   0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
 +   0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
 +   0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
 +   0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
 +   0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
 +   0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
 +   0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
 +   0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
 +   0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
 +   0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
 +   0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
 +   0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
 +   0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
 +   0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
 +   0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
 +   0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
 +   0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
 +   0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
 +   0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
 +   0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
 +   0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
 +   0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
 +   0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
 +   0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
 +   0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
 +   0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
 +   0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
 +   0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
 +   0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
 +   0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
 +   0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
 +   0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
 +   0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
 +   0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
 +   0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8a,
 +   0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
 +   0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
 +   0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
 +   0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
 +   0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
 +   0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
 +   0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
 +   0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
 +   0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
 +   0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
 +   0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
 +   0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
 +   0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
 +   0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
 +   0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
 +   0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
 +   0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
 +   0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
 +   0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
 +   0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
 +   0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
 +   0x8a, 0x8a, 0x8a, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
 +   0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
 +   0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
 +   0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
 +   0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
 +   0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
 +   0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
 +   0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
 +   0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
 +   0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
 +   0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
 +   0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
 +   0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
 +   0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
 +   0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
 +   0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
 +   0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
 +   0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
 +   0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
 +   0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
 +   0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
 +   0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x88, 0x88, 0x88, 0x88, 0x88,
 +   0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
 +   0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
 +   0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
 +   0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
 +   0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
 +   0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
 +   0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
 +   0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
 +   0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
 +   0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
 +   0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
 +   0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
 +   0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
 +   0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
 +   0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
 +   0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
 +   0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
 +   0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
 +   0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
 +   0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
 +   0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87,
 +   0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
 +   0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
 +   0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
 +   0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
 +   0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
 +   0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
 +   0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
 +   0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
 +   0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
 +   0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
 +   0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
 +   0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
 +   0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
 +   0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
 +   0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
 +   0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
 +   0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
 +   0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
 +   0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
 +   0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
 +   0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
 +   0x87, 0x87, 0x87, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
 +   0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
 +   0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
 +   0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
 +   0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
 +   0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
 +   0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
 +   0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
 +   0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
 +   0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
 +   0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
 +   0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
 +   0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
 +   0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
 +   0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
 +   0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
 +   0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
 +   0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
 +   0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
 +   0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
 +   0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
 +   0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x85, 0x85, 0x85, 0x85, 0x85,
 +   0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
 +   0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
 +   0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
 +   0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
 +   0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
 +   0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
 +   0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
 +   0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
 +   0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
 +   0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
 +   0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
 +   0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
 +   0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
 +   0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
 +   0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
 +   0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
 +   0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
 +   0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
 +   0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
 +   0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
 +   0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x84,
 +   0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
 +   0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
 +   0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
 +   0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
 +   0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
 +   0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
 +   0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
 +   0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
 +   0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
 +   0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
 +   0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
 +   0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
 +   0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
 +   0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
 +   0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
 +   0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
 +   0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
 +   0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
 +   0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
 +   0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
 +   0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
 +   0x84, 0x84, 0x84, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
 +   0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
 +   0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
 +   0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
 +   0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
 +   0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
 +   0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
 +   0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
 +   0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
 +   0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
 +   0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
 +   0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
 +   0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
 +   0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
 +   0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
 +   0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
 +   0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
 +   0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
 +   0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
 +   0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
 +   0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
 +   0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x82, 0x82, 0x82, 0x82, 0x82,
 +   0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
 +   0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
 +   0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
 +   0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
 +   0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
 +   0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
 +   0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
 +   0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
 +   0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
 +   0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
 +   0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
 +   0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
 +   0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
 +   0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
 +   0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
 +   0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
 +   0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
 +   0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
 +   0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
 +   0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
 +   0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x81,
 +   0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
 +   0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
 +   0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
 +   0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
 +   0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
 +   0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
 +   0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
 +   0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
 +   0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
 +   0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
 +   0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
 +   0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
 +   0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
 +   0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
 +   0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
 +   0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
 +   0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
 +   0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
 +   0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
 +   0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
 +   0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
 +   0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
 +   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
 +   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
 +   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
 +   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
 +   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
 +   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
 +   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
 +   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
 +   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
 +   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
 +   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
 +   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
 +   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
 +   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
 +   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
 +   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
 +   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
 +   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
 +   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
 +   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
 +   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
 +   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
 +   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
 +   0x80, 0x80, 0x80, 0x80
 +};
 +
 +#endif /* FAST_ULAW_CONVERSION */
 +
 +/* The following code was used to generate the lookup tables */
 +#if 0
 +int main()
 +{
 +    int x, y, find2a = 0;
 +
 +    y = 0;
 +    printf("int16_t _st_alaw2linear16[256] = {\n  ");
 +    for (x = 0; x < 256; x++)
 +    {
 +	printf("%8d,", st_alaw2linear16(x));
 +	y++;
 +	if (y == 7)
 +	{
 +	    y = 0;
 +	    printf("\n  ");
 +	}
 +    }
 +
 +    printf("\n};\n\nuint8_t _st_13linear2alaw[0x2000] = {\n  ");
 +    y = 0;
 +    for (x = 0; x < 0x2000; x++)
 +    {
 +	printf(" 0x%02x,", st_13linear2alaw((-0x1000)+x));
 +	y++;
 +	if (y == 12)
 +	{
 +	    y = 0;
 +	    printf("\n  ");
 +	}
 +    }
 +
 +    printf("\n};\n\nint16_t _st_ulaw2linear16[256] = {\n  ");
 +    y = 0;
 +    for (x = 0; x < 256; x++)
 +    {
 +	printf("%8d,", st_ulaw2linear16(x));
 +	y++;
 +	if (y == 7)
 +	{
 +	    y = 0;
 +	    printf("\n  ");
 +	}
 +    }
 +
 +    printf("\n};\n\nuint8_t _st_14linear2ulaw[0x4000] = {\n  ");
 +    y = 0;
 +    for (x = 0; x < 0x4000; x++)
 +    {
 +	printf(" 0x%02x,", st_14linear2ulaw((-0x2000)+x));
 +	y++;
 +	if (y == 12)
 +	{
 +	    y = 0;
 +	    printf("\n  ");
 +	}
 +    }
 +    printf("\n};\n");
 +
 +}
 +#endif
 +
 +/* The following is not used by SoX but kept for reference */
 +#if 0
 +/* copy from CCITT G.711 specifications */
 +unsigned char _u2a[128] = {			/* u- to A-law conversions */
 +	1,	1,	2,	2,	3,	3,	4,	4,
 +	5,	5,	6,	6,	7,	7,	8,	8,
 +	9,	10,	11,	12,	13,	14,	15,	16,
 +	17,	18,	19,	20,	21,	22,	23,	24,
 +	25,	27,	29,	31,	33,	34,	35,	36,
 +	37,	38,	39,	40,	41,	42,	43,	44,
 +	46,	48,	49,	50,	51,	52,	53,	54,
 +	55,	56,	57,	58,	59,	60,	61,	62,
 +	64,	65,	66,	67,	68,	69,	70,	71,
 +	72,	73,	74,	75,	76,	77,	78,	79,
 +/* corrected:
 +	81,	82,	83,	84,	85,	86,	87,	88, 
 +   should be: */
 +	80,	82,	83,	84,	85,	86,	87,	88,
 +	89,	90,	91,	92,	93,	94,	95,	96,
 +	97,	98,	99,	100,	101,	102,	103,	104,
 +	105,	106,	107,	108,	109,	110,	111,	112,
 +	113,	114,	115,	116,	117,	118,	119,	120,
 +	121,	122,	123,	124,	125,	126,	127,	128};
 +
 +unsigned char _a2u[128] = {			/* A- to u-law conversions */
 +	1,	3,	5,	7,	9,	11,	13,	15,
 +	16,	17,	18,	19,	20,	21,	22,	23,
 +	24,	25,	26,	27,	28,	29,	30,	31,
 +	32,	32,	33,	33,	34,	34,	35,	35,
 +	36,	37,	38,	39,	40,	41,	42,	43,
 +	44,	45,	46,	47,	48,	48,	49,	49,
 +	50,	51,	52,	53,	54,	55,	56,	57,
 +	58,	59,	60,	61,	62,	63,	64,	64,
 +	65,	66,	67,	68,	69,	70,	71,	72,
 +/* corrected:
 +	73,	74,	75,	76,	77,	78,	79,	79,
 +   should be: */
 +	73,	74,	75,	76,	77,	78,	79,	80,
 +
 +	80,	81,	82,	83,	84,	85,	86,	87,
 +	88,	89,	90,	91,	92,	93,	94,	95,
 +	96,	97,	98,	99,	100,	101,	102,	103,
 +	104,	105,	106,	107,	108,	109,	110,	111,
 +	112,	113,	114,	115,	116,	117,	118,	119,
 +	120,	121,	122,	123,	124,	125,	126,	127};
 +
 +/* A-law to u-law conversion */
 +unsigned char sa_alaw2ulaw(
 +	unsigned char	aval)
 +{
 +	aval &= 0xff;
 +	return (unsigned char) ((aval & 0x80) ? (0xFF ^ _a2u[aval ^ 0xD5]) :
 +	    (0x7F ^ _a2u[aval ^ 0x55]));
 +}
 +
 +/* u-law to A-law conversion */
 +unsigned char sa_ulaw2alaw(
 +	unsigned char	uval)
 +{
 +	uval &= 0xff;
 +	return (unsigned char) ((uval & 0x80) ? (0xD5 ^ (_u2a[0xFF ^ uval] - 1)) :
 +	    (unsigned char) (0x55 ^ (_u2a[0x7F ^ uval] - 1)));
 +}
 +#endif
 diff --git a/src/g711.h b/src/g711.h new file mode 100644 index 0000000..ef43e3f --- /dev/null +++ b/src/g711.h @@ -0,0 +1,40 @@ +#ifndef foosydneyg711hfoo +#define foosydneyg711hfoo + +/* g711.h - include for G711 u-law and a-law conversion routines +** +** Copyright (C) 2001 Chris Bagwell +** +** Permission to use, copy, modify, and distribute this software and its +** documentation for any purpose and without fee is hereby granted, provided +** that the above copyright notice appear in all copies and that both that +** copyright notice and this permission notice appear in supporting +** documentation.  This software is provided "as is" without express or +** implied warranty. +*/ + +/** Copied from sox */ + +#include <inttypes.h> + +#ifdef FAST_ALAW_CONVERSION +extern uint8_t _sa_13linear2alaw[0x2000]; +extern int16_t _sa_alaw2linear16[256]; +#define sa_13linear2alaw(sw) (_sa_13linear2alaw[(sw + 0x1000)]) +#define sa_alaw2linear16(uc) (_sa_alaw2linear16[uc]) +#else +unsigned char sa_13linear2alaw(int16_t pcm_val); +int16_t sa_alaw2linear16(unsigned char); +#endif + +#ifdef FAST_ULAW_CONVERSION +extern uint8_t _sa_14linear2ulaw[0x4000]; +extern int16_t _sa_ulaw2linear16[256]; +#define sa_14linear2ulaw(sw) (_sa_14linear2ulaw[(sw + 0x2000)]) +#define sa_ulaw2linear16(uc) (_sa_ulaw2linear16[uc]) +#else +unsigned char sa_14linear2ulaw(int16_t pcm_val); +int16_t sa_ulaw2linear16(unsigned char); +#endif + +#endif diff --git a/src/interleave.c b/src/interleave.c new file mode 100644 index 0000000..d0470f7 --- /dev/null +++ b/src/interleave.c @@ -0,0 +1,64 @@ +#include <inttypes.h> + +#include "macro.h" +#include "interleave.h" + +static void interleave8(void *_dst, size_t dstr, const void *_src, size_t sstr, size_t bytes) { +    uint8_t *dst = _dst; +    const uint8_t *src = _src; + +    for (; bytes > 0; bytes--, src += sstr, dst += dstr) +        *dst = *src; +} + +static void interleave16(void *_dst, size_t dstr, const void *_src, size_t sstr, size_t bytes) { +    uint16_t *dst = _dst; +    const uint16_t *src = _src; +    unsigned n = bytes / sizeof(uint16_t); + +    for (; n > 0; n--, src += sstr/sizeof(uint16_t), dst += dstr/sizeof(uint16_t)) +        *dst = *src; +} + +static void interleave24(void *_dst, size_t dstr, const void *_src, size_t sstr, size_t bytes) { +    uint8_t *dst = _dst; +    const uint8_t *src = _src; +    unsigned n = bytes / 3; + +    for (; n > 0; n--, src += sstr/3, dst += dstr/3) { +        dst[0] = src[0]; +        dst[1] = src[1]; +        dst[2] = src[2]; +    } +} + +static void interleave32(void *_dst, size_t dstr, const void *_src, size_t sstr, size_t bytes) { +    uint32_t *dst = _dst; +    const uint32_t *src = _src; +    unsigned n = bytes / sizeof(uint32_t); + +    for (; n > 0; n--, src += sstr/sizeof(uint32_t), dst += dstr/sizeof(uint32_t)) +        *dst = *src; +} + +sa_interleave_func_t sa_get_interleave_func(sa_pcm_format_t f) { +     +    static const sa_interleave_func_t funcs[_SA_PCM_FORMAT_MAX] = { +        [SA_PCM_FORMAT_U8] = interleave8, +        [SA_PCM_FORMAT_ULAW] = interleave8, +        [SA_PCM_FORMAT_ALAW] = interleave8, +        [SA_PCM_FORMAT_S16_LE] = interleave16, +        [SA_PCM_FORMAT_S16_BE] = interleave16, +        [SA_PCM_FORMAT_S24_LE] = interleave24, +        [SA_PCM_FORMAT_S24_BE] = interleave24, +        [SA_PCM_FORMAT_S32_LE] = interleave32, +        [SA_PCM_FORMAT_S32_BE] = interleave32, +        [SA_PCM_FORMAT_FLOAT32_LE] = interleave32, +        [SA_PCM_FORMAT_FLOAT32_BE] = interleave32, +    }; +             +    sa_assert(f < _SA_PCM_FORMAT_MAX);  + +    return funcs[f]; +} + diff --git a/src/interleave.h b/src/interleave.h new file mode 100644 index 0000000..ed4a527 --- /dev/null +++ b/src/interleave.h @@ -0,0 +1,12 @@ +#ifndef foosydneyhinterleavehfoo +#define foosydneyhinterleavehfoo + +#include <sys/types.h> + +#include "sydney.h" + +typedef void (*sa_interleave_func_t) (void *dst, size_t dstr, const void *src, size_t sstr, size_t bytes); + +sa_interleave_func_t sa_get_interleave_func(sa_pcm_format_t f); + +#endif diff --git a/src/llist.h b/src/llist.h new file mode 100644 index 0000000..3d42218 --- /dev/null +++ b/src/llist.h @@ -0,0 +1,70 @@ +#ifndef foosydneyllistfoo +#define foosydneyllistfoo + + +#include "macro.h" + +#define SA_LLIST_HEAD(t,head) t* head + +#define SA_LLIST_ITEM(t,name) t* name##_prev, *name##_next + +#define SA_LLIST_HEAD_INIT(t,head) (head) = (t*) NULL + +#define SA_LLIST_ITEM_INIT(t,name,item) do { \ +                               t *_item = (item); \ +                               sa_assert(_item); \ +                               _item->name##_prev = _item->name##_next = NULL; \ +                               } while(0) + +#define SA_LLIST_PREPEND(t,name,head,item) do { \ +                                        t **_head = &(head), *_item = (item); \ +                                        sa_assert(_item); \ +                                        if ((_item->name##_next = *_head)) \ +                                            _item->name##_next->name##_prev = _item; \ +                                        _item->name##_prev = NULL; \ +                                        *_head = _item; \ +                                        } while (0) + +#define SA_LLIST_INSERT_BEFORE(t,name,head,at,item) do { \ +                                        t **_head = &(head), *_item = (item), *_at = (at); \ +                                        sa_assert(_item); \ +                                        sa_assert(_at); \ +                                        if ((_item->name##_prev = _at->name##_prev)) { \ +                                            sa_assert(_item->name##_prev->name##_next == _at); \ +                                            _item->name##_prev->name##_next = _item; \ +                                        } else {\ +                                            sa_assert(*_head == _at); \ +                                            *_head = _item; \ +                                        }  \ +                                        _item->name##_next = _at; \ +                                        _at->name##_prev = _item; \ +                                        } while (0) + +#define SA_LLIST_INSERT_AFTER(t,name,head,at,item) do { \ +                                        t *_item = (item), *_at = (at); \ +                                        sa_assert(_item); \ +                                        sa_assert(_at); \ +                                        if ((_item->name##_next = _at->name##_next)) { \ +                                            sa_assert(_item->name##_next->name##_prev == _at); \ +                                            _item->name##_next->name##_prev = _item; \ +                                        } \ +                                        _item->name##_prev = _at; \ +                                        _at->name##_next = _item; \ +                                        } while (0) + +#define SA_LLIST_REMOVE(t,name,head,item) do { \ +                                    t **_head = &(head), *_item = (item); \ +                                    sa_assert(_item); \ +                                    if (_item->name##_next) \ +                                        _item->name##_next->name##_prev = _item->name##_prev; \ +                                    if (_item->name##_prev) \ +                                        _item->name##_prev->name##_next = _item->name##_next; \ +                                    else {\ +                                        sa_assert(*_head == _item); \ +                                        *_head = _item->name##_next; \ +                                    } \ +                                    _item->name##_next = _item->name##_prev = NULL; \ +                                    } while(0) + + +#endif diff --git a/src/macro.h b/src/macro.h new file mode 100644 index 0000000..d664c3e --- /dev/null +++ b/src/macro.h @@ -0,0 +1,104 @@ +#ifndef foomacrohfoo +#define foomacrohfoo + +#include <stdio.h> +#include <assert.h> + +#ifdef __GNUC__ +#define SA_PRETTY_FUNCTION __PRETTY_FUNCTION__ +#else +#define SA_PRETTY_FUNCTION "" +#endif + +#define sa_return_if_fail(expr) \ +    do { \ +        if (!(expr)) { \ +             fprintf(stderr, "%s: Assertion <%s> failed.\n", SA_PRETTY_FUNCTION, #expr ); \ +            return; \ +        } \ +    } while(0) + +#define sa_return_val_if_fail(expr, val) \ +    do { \ +        if (!(expr)) { \ +            fprintf(stderr, "%s: Assertion <%s> failed.\n", SA_PRETTY_FUNCTION, #expr ); \ +            return (val); \ +        } \ +    } while(0) + +#define sa_return_if_fail_mutex(m, expr)         \ +    do { \ +        if (!(expr)) { \ +            fprintf(stderr, "%s: Assertion <%s> failed.\n", SA_PRETTY_FUNCTION, #expr ); \ +            sa_mutex_unlock(m);                                                       \ +            return; \ +        } \ +    } while(0) + +#define sa_return_val_if_fail_mutex(m, expr, val)        \ +    do { \ +        if (!(expr)) { \ +                                                                        \ +            fprintf(stderr, "%s: Assertion <%s> failed.\n", SA_PRETTY_FUNCTION, #expr ); \ +            sa_mutex_unlock(m);                                                       \ +            return (val); \ +        } \ +    } while(0) + +#define sa_assert assert + +/* An assert which guarantees side effects of x */ +#ifdef NDEBUG +#define sa_assert_se(x) x +#else +#define sa_assert_se(x) sa_assert(x) +#endif + +#define sa_assert_not_reached() sa_assert(!"Should not be reached.") + +#define sa_assert_success(x) do {               \ +        int _r = (x);                           \ +        sa_assert(_r == 0);                     \ +    } while(0) + +#define SA_ELEMENTSOF(x) (sizeof(x)/sizeof((x)[0])) + +#ifndef MAX +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#endif + +#ifndef MIN +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif + +#ifndef CLAMP +#define CLAMP(x, low, high)  (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x))) +#endif + +#ifndef FALSE +#define FALSE (0) +#endif + +#ifndef TRUE +#define TRUE (!FALSE) +#endif + +#define SA_PTR_TO_UINT(p) ((unsigned int) (unsigned long) (p)) +#define SA_UINT_TO_PTR(u) ((void*) (unsigned long) (u)) + +#define SA_PTR_TO_UINT32(p) ((uint32_t) SA_PTR_TO_UINT(p)) +#define SA_UINT32_TO_PTR(u) SA_UINT_TO_PTR((uint32_t) u) + +#define SA_PTR_TO_INT(p) ((int) SA_PTR_TO_UINT(p)) +#define SA_INT_TO_PTR(u) SA_UINT_TO_PTR((int) u) + +#define SA_PTR_TO_INT32(p) ((int32_t) SA_PTR_TO_UINT(p)) +#define SA_INT32_TO_PTR(u) SA_UINT_TO_PTR((int32_t) u) + +static inline size_t sa_align(size_t l) { +    return (((l + sizeof(void*) - 1) / sizeof(void*)) * sizeof(void*)); +} + +#define SA_ALIGN(x) (sa_align(x)) + +#endif diff --git a/src/malloc.c b/src/malloc.c new file mode 100644 index 0000000..6a89554 --- /dev/null +++ b/src/malloc.c @@ -0,0 +1,13 @@ +#include <string.h> + +#include "malloc.h" + +void* sa_memdup(const void* p, size_t size) { +    void *r; + +    if (!(r = sa_malloc(size))) +        return NULL; + +    memcpy(r, p, size); +    return r; +} diff --git a/src/malloc.h b/src/malloc.h new file mode 100644 index 0000000..bcaf53e --- /dev/null +++ b/src/malloc.h @@ -0,0 +1,19 @@ +#ifndef foomallochfoo +#define foomallochfoo + +#include <stdlib.h> +#include <string.h> + +#define sa_malloc malloc +#define sa_free free +#define sa_malloc0(size) calloc(1, (size)) +#define sa_strdup strdup +#define sa_strndup strndup + +void* sa_memdup(const void* p, size_t size); + +#define sa_new(t, n) ((t*) sa_malloc(sizeof(t)*(n))) +#define sa_new0(t, n) ((t*) sa_malloc0(sizeof(t)*(n))) +#define sa_newdup(t, p, n) ((t*) sa_memdup(p, sizeof(t)*(n))) + +#endif diff --git a/src/meta-name-table.gperf b/src/meta-name-table.gperf new file mode 100644 index 0000000..69db483 --- /dev/null +++ b/src/meta-name-table.gperf @@ -0,0 +1,11 @@ +struct meta_name { const char* name; int idx; }; +%% +sydney.client-name, 0 +sydney.process-id, 1  +sydney.language, 2 +sydney.stream-name, 3 +sydney.icon-name, 4 +sydney.icon-png, 5 +sydney.role, 6 +sydney.x11-xid, 7 +sydney.x11-display, 8 diff --git a/src/mutex.c b/src/mutex.c new file mode 100644 index 0000000..12a4f4a --- /dev/null +++ b/src/mutex.c @@ -0,0 +1,97 @@ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <pthread.h> +#include <errno.h> + +#include "macro.h" +#include "malloc.h" +#include "mutex.h" + +struct sa_mutex { +    pthread_mutex_t mutex; +}; + +struct sa_cond { +    pthread_cond_t cond; +}; + +sa_mutex_t* sa_mutex_new(int recursive) { +    sa_mutex_t *m; +    pthread_mutexattr_t attr; + +    pthread_mutexattr_init(&attr); + +    if (recursive) +        sa_assert_success(pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)); + +    if (!(m = sa_new(sa_mutex_t, 1))) +        return NULL; + +    sa_assert_success(pthread_mutex_init(&m->mutex, &attr)); +    return m; +} + +void sa_mutex_free(sa_mutex_t *m) { +    sa_assert(m); + +    sa_assert_success(pthread_mutex_destroy(&m->mutex)); +    sa_free(m); +} + +void sa_mutex_lock(sa_mutex_t *m) { +    sa_assert(m); + +    sa_assert_success(pthread_mutex_lock(&m->mutex)); +} + +int sa_mutex_try_lock(sa_mutex_t *m) { +    int e; +    sa_assert(m); + +    if ((e = pthread_mutex_trylock(&m->mutex)) == 0) +        return 1; + +    sa_assert(e == EBUSY); +    return 0; +} + +void sa_mutex_unlock(sa_mutex_t *m) { +        sa_assert(m); + +    sa_assert_success(pthread_mutex_unlock(&m->mutex)); +} + +sa_cond_t *sa_cond_new(void) { +    sa_cond_t *c; + +    if (!(c = sa_new(sa_cond_t, 1))) +        return NULL; + +    sa_assert_success(pthread_cond_init(&c->cond, NULL)); +    return c; +} + +void sa_cond_free(sa_cond_t *c) { +    sa_assert(c); + +    sa_assert_success(pthread_cond_destroy(&c->cond)); +    sa_free(c); +} + +void sa_cond_signal(sa_cond_t *c, int broadcast) { +    sa_assert(c); + +    if (broadcast) +        sa_assert_success(pthread_cond_broadcast(&c->cond)); +    else +        sa_assert_success(pthread_cond_signal(&c->cond)); +} + +int sa_cond_wait(sa_cond_t *c, sa_mutex_t *m) { +    sa_assert(c); +    sa_assert(m); + +    return pthread_cond_wait(&c->cond, &m->mutex); +} diff --git a/src/mutex.h b/src/mutex.h new file mode 100644 index 0000000..e83feb8 --- /dev/null +++ b/src/mutex.h @@ -0,0 +1,19 @@ +#ifndef foosydneymutexhfoo +#define foosydneymutexhfoo + +typedef struct sa_mutex sa_mutex_t; + +sa_mutex_t* sa_mutex_new(int recursive); +void sa_mutex_free(sa_mutex_t *m); +void sa_mutex_lock(sa_mutex_t *m); +void sa_mutex_unlock(sa_mutex_t *m); +int sa_mutex_try_lock(sa_mutex_t *m); + +typedef struct sa_cond sa_cond_t; + +sa_cond_t *sa_cond_new(void); +void sa_cond_free(sa_cond_t *c); +void sa_cond_signal(sa_cond_t *c, int broadcast); +int sa_cond_wait(sa_cond_t *c, sa_mutex_t *m); + +#endif diff --git a/src/once.c b/src/once.c new file mode 100644 index 0000000..5dc9764 --- /dev/null +++ b/src/once.c @@ -0,0 +1,58 @@ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <pthread.h> +#include <assert.h> + +#include "once.h" +#include "mutex.h" +#include "malloc.h" +#include "macro.h" + +static sa_mutex_t *global_mutex;  +static pthread_once_t global_mutex_once = PTHREAD_ONCE_INIT; + +static void global_mutex_once_func(void) {  +    global_mutex = sa_mutex_new(0); +}  + +int sa_once(sa_once_t *control, sa_once_func_t func) { +    int r; +     +    assert(control);  +    assert(func);  +     +    /* Create the global mutex */ +    sa_assert_success(pthread_once(&global_mutex_once, global_mutex_once_func)); + +    if (!global_mutex) +        return -1; + +    r = 0; +     +    /* Create the local mutex */ +    sa_mutex_lock(global_mutex);  +    if (!control->mutex) { +        if (!(control->mutex = sa_mutex_new(1))) +            r = -1; +    } +    sa_mutex_unlock(global_mutex); + +    if (r) +        return -1; +     +    /* Execute function */ +    sa_mutex_lock(control->mutex); +    if (!control->once_value) { +        control->once_value = 1; +        func(); +    } +    sa_mutex_unlock(control->mutex);  + +    /* Caveat: We have to make sure that the once func has completed +     * before returning, even if the once func is not actually +     * executed by us. Hence the awkward locking. */ + +    return 0; +}  diff --git a/src/once.h b/src/once.h new file mode 100644 index 0000000..a374529 --- /dev/null +++ b/src/once.h @@ -0,0 +1,17 @@ +#ifndef foosydneyoncehfoo +#define foosydneyoncehfoo + +#include "mutex.h" + +typedef struct sa_once { +    unsigned int once_value; +    sa_mutex_t *mutex; +} sa_once_t; + +#define SA_ONCE_INIT { .once_value = 0, .mutex = NULL } + +typedef void (*sa_once_func_t) (void); + +int sa_once(sa_once_t *o, sa_once_func_t f); + +#endif diff --git a/src/oss.c b/src/oss.c new file mode 100644 index 0000000..d09f8aa --- /dev/null +++ b/src/oss.c @@ -0,0 +1,858 @@ +#include <signal.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <sys/ioctl.h> +#include <sys/soundcard.h> +#include <poll.h> +#include <sys/types.h> +#include <sys/socket.h> + +#include "sydney.h" +#include "common.h" +#include "macro.h" +#include "malloc.h" +#include "converter.h" +#include "driver.h" +#include "thread.h" +#include "bufferq.h" + +#define DEFAULT_DEVICE "/dev/dsp" +#define DRIVER_NAME "oss" + +typedef struct oss_stream oss_stream_t; +#define OSS_STREAM(x) ((oss_stream_t*) (x->private)) + +struct oss_stream { +    sa_stream_t *parent; +    int fd; +    pcm_attrs_t real_pcm_attrs; +    sa_converter_t converter_read, converter_write; +    size_t read_fragment_size, write_fragment_size; +    unsigned read_nfragments, write_nfragments; +    sa_thread_t *thread; +    int socket_fds[2]; +    sa_bufferq_t bufferq; +}; + +static int simple_log2(int v) { +    int k = 0; + +    for (;;) { +        v >>= 1; +        if (!v) break; +        k++; +    } + +    return k; +} + +static size_t fixup_bps(size_t s, size_t bps1, size_t bps2) { +    return (s*bps2)/bps1; +} + +int driver_open(sa_stream_t *s) { +    oss_stream_t *oss; +    char *n; +    int f, arg, bs, r, phase, i, found, suggested, fs, l, m; +    unsigned c; +    size_t real_bps = 0, bps; +    int loops = 0; +     +    static const int format_map[_SA_PCM_FORMAT_MAX] = { +        [SA_PCM_FORMAT_U8] = AFMT_U8, +        [SA_PCM_FORMAT_ULAW] = AFMT_MU_LAW, +        [SA_PCM_FORMAT_ALAW] = AFMT_A_LAW, +        [SA_PCM_FORMAT_S16_LE] = AFMT_S16_LE, +        [SA_PCM_FORMAT_S16_BE] = AFMT_S16_BE, +        [SA_PCM_FORMAT_S24_LE] = AFMT_S16_NE, /* OSS doesn't know this format, hence we pick the best we can */ +        [SA_PCM_FORMAT_S24_BE] = AFMT_S16_NE, +        [SA_PCM_FORMAT_S32_LE] = AFMT_S16_NE, +        [SA_PCM_FORMAT_S32_BE] = AFMT_S16_NE, +        [SA_PCM_FORMAT_FLOAT32_LE] = AFMT_S16_NE, +        [SA_PCM_FORMAT_FLOAT32_BE] = AFMT_S16_NE +    }; +    static const int try_rates[] = { 8000, 16000, 32000, 44100, 48000, 96000, 192000 }; + +    if (s->driver && strcmp(s->driver, DRIVER_NAME)) +        return SA_ERROR_NO_DRIVER; + +    if (!(s->private = oss = sa_new0(oss_stream_t, 1))) +        return SA_ERROR_OOM; + +    oss->parent = s; +    oss->socket_fds[0] = oss->socket_fds[1] = -1; + +    n = s->device ? s->device : DEFAULT_DEVICE; +    if (!s->codec) +        bps = s->pcm_frame_size * s->pcm_attrs.rate; + +    for (;;) { +        /* We need to loop here, because we have to call SETFRAGMENT +         * as first ioctl after the open, at a point where we +         * don't now yet the sample type, freq and the number of +         * channels we actually settled on. Hence we have to loop +         * here: if the sampling format is too far off we have to call +         * SETFRAGMENT again which can do only after reopening the +         * device again. */ + +        if ((oss->fd = open(n, s->mode == SA_MODE_RDONLY ? O_RDONLY : (s->mode == SA_MODE_WRONLY ? O_WRONLY : O_RDWR) | O_NOCTTY | O_NONBLOCK)) < 0) { +             +            if (errno == ENODEV || errno == ENOENT) +                r = SA_ERROR_NO_DEVICE; +            else +                r = SA_ERROR_SYSTEM; +             +            goto fail; +        } +         +        fcntl(oss->fd, F_SETFL, fcntl(oss->fd, F_GETFL) & ~O_NONBLOCK); /* FIXME*/ +         +        if (!s->device) { +            if (!(n = sa_strdup(n))) { +                r = SA_ERROR_OOM; +                goto fail; +            } +             +            s->device = n; +        } + +        /* Set fragment settings */ +        if (s->mode & SA_MODE_WRONLY) { +            bs = s->write_lower_watermark; +        } +         +        if (s->mode & SA_MODE_RDONLY) { +            int rbs; +             +            rbs = s->read_upper_watermark; +             +            if (s->mode & SA_MODE_WRONLY) +                bs = bs > rbs ? bs : rbs; +            else +                bs = rbs; +        } + +        if (!s->codec && real_bps) +            bs = fixup_bps(bs, bps, real_bps); + +        fs = bs/4; +        l = simple_log2(fs); +        if (l < 1) l = 1; +        m = (bs+(1<<l)-1)/(1<<l); +        if (m < 2) m = 2; +        if (m > 0x7FFF) m = 0x7FFF; + +        printf("Asking OSS for: %u fragments, %u fragsize\n", m, 1 << l); +         +        arg = (m << 16) | l; +         +        ioctl(oss->fd, SNDCTL_DSP_SETFRAGMENT, &arg); +        /* We ignore errors on this call, since it's merely a hint anyway */ +         +        if (s->codec) { +             +            if (strcmp(s->codec, SA_CODEC_AC3) == 0) +                f = AFMT_AC3; +            else if (strcmp(s->codec, SA_CODEC_MPEG) == 0) +                f = AFMT_MPEG; +            else { +                r = SA_ERROR_NO_CODEC; +                goto fail; +            } +             +        } else +            f = format_map[s->pcm_attrs.format]; +         +        bs = 0; +         +        for (;;) { +            arg = f; +             +            if (ioctl(oss->fd, SNDCTL_DSP_SETFMT, &arg) < 0) { +                r = SA_ERROR_SYSTEM; +                goto fail; +            } +             +            if (arg == f) +                break; +             +            /* Hmm, the device doesn't support what we're looking for, +             * let's try our luck */ +             +            if (f == AFMT_S16_LE && !bs) {  +                f = AFMT_S16_BE; +                bs = 1; +            } else if (f == AFMT_S16_BE && !bs) { +                f = AFMT_S16_LE; +                bs = 1; +            } else if (f == AFMT_S16_LE || f == AFMT_S16_BE) { +                f = AFMT_MU_LAW; +                bs = 0; +            } else if (f == AFMT_MU_LAW && !bs) { +                f = AFMT_A_LAW; +                bs = 1; +            } else if (f == AFMT_A_LAW && !bs) { +                f = AFMT_MU_LAW; +                bs = 1; +            } else if (f == AFMT_A_LAW || f == AFMT_MU_LAW) { +                f = AFMT_U8; +            } else if (f == AFMT_AC3 || f == AFMT_MPEG) { +                r = SA_ERROR_NO_CODEC; +                goto fail; +            } else { +                r = SA_ERROR_NO_PCM_FORMAT; +                goto fail; +            } +        } +         +        if (!s->codec) { +             +            switch (f) { +                case AFMT_MU_LAW: +                    oss->real_pcm_attrs.format = SA_PCM_FORMAT_ULAW; +                    break; +                     +                case AFMT_A_LAW: +                    oss->real_pcm_attrs.format = SA_PCM_FORMAT_ALAW; +                    break; +                     +                case AFMT_U8: +                    oss->real_pcm_attrs.format = SA_PCM_FORMAT_U8; +                    break; +                     +                case AFMT_S16_LE: +                    oss->real_pcm_attrs.format = SA_PCM_FORMAT_S16_LE; +                    break; +                     +                case AFMT_S16_BE: +                    oss->real_pcm_attrs.format = SA_PCM_FORMAT_S16_BE; +                    break; +                     +                default: +                    sa_assert_not_reached(); +            } +             +             +            found = 0; +             +            if (s->adjust_nchannels >= 0) { +                 +                /* First try more channels ... */ +                for (c = s->pcm_attrs.nchannels; c < 8 || c == s->pcm_attrs.nchannels; c ++) { +                    arg = c; +                    if (ioctl(oss->fd, SNDCTL_DSP_CHANNELS, &arg) < 0) { +                        r = SA_ERROR_SYSTEM; +                        goto fail; +                    } +                     +                    if (arg == (int) c) { +                        found = 1; +                        break; +                    } +                } +                 +                /* ... then try less channels */ +                if (!found) { +                    for (c = s->pcm_attrs.nchannels - 1; c > 0; c --) { +                        arg = c; +                        if (ioctl(oss->fd, SNDCTL_DSP_CHANNELS, &arg) < 0) { +                            r = SA_ERROR_SYSTEM; +                            goto fail; +                        } +                         +                        if (arg == (int) c) { +                            found = 1; +                            break; +                        } +                    } +                } +            } else { +                 +                /* First try less channels ... */ +                for (c = s->pcm_attrs.nchannels; c > 0; c --) { +                    arg = c; +                    if (ioctl(oss->fd, SNDCTL_DSP_CHANNELS, &arg) < 0) { +                        r = SA_ERROR_SYSTEM; +                        goto fail; +                    } +                     +                    if (arg == (int) c) { +                        found = 1; +                        break; +                    } +                } +                 +                /* ... then try more channels */ +                if (!found) { +                    for (c = s->pcm_attrs.nchannels + 1; c < 8; c ++) { +                        arg = c; +                        if (ioctl(oss->fd, SNDCTL_DSP_CHANNELS, &arg) < 0) { +                            r = SA_ERROR_SYSTEM; +                            goto fail; +                        } +                         +                        if (arg == (int) c) { +                            found = 1; +                            break; +                        } +                    } +                }             +            } +             +            if (!found) { +                errno = EIO; +                r = SA_ERROR_SYSTEM; +                goto fail; +            } +             +            oss->real_pcm_attrs.nchannels = c; +             +            if (!(oss->real_pcm_attrs.channel_map = sa_new(sa_channel_t, c))) { +                r = SA_ERROR_OOM; +                goto fail; +            } +             +            switch (c) { +                case 8: +                    oss->real_pcm_attrs.channel_map[7] = SA_CHANNEL_REAR_RIGHT; +                case 7: +                    oss->real_pcm_attrs.channel_map[6] = SA_CHANNEL_REAR_LEFT; +                case 6: +                    oss->real_pcm_attrs.channel_map[5] = SA_CHANNEL_FRONT_LEFT; +                case 5: +                    oss->real_pcm_attrs.channel_map[4] = SA_CHANNEL_FRONT_RIGHT; +                case 4: +                    oss->real_pcm_attrs.channel_map[3] = SA_CHANNEL_LFE; +                case 3: +                    oss->real_pcm_attrs.channel_map[2] = SA_CHANNEL_CENTER; +                case 2: +                    oss->real_pcm_attrs.channel_map[1] = SA_CHANNEL_RIGHT; +                    oss->real_pcm_attrs.channel_map[0] = SA_CHANNEL_LEFT; +                    break; +                case 1: +                    oss->real_pcm_attrs.channel_map[0] = SA_CHANNEL_MONO; +                    break; +            } +             +            r = s->pcm_attrs.rate; +             +            if (r < 8000) +                r = 8000; +             +            suggested = 0; +            phase = 0; +             +            for (;;) { +                arg = r; +             +                if (ioctl(oss->fd, SNDCTL_DSP_SPEED, &arg) < 0) { +                    r = SA_ERROR_SYSTEM; +                    goto fail; +                } + +                sa_assert(arg > 0); +             +                if (arg >= r*0.95 || arg <= r *1.05) +                    break; + +                if (arg > suggested) +                    suggested = arg; + +                if (s->adjust_rate >= 0) { +                 +                    if (phase == 0) { +                        /* Find the next higher sample rate to try */ +                     +                        for (i = 0; i < (int) SA_ELEMENTSOF(try_rates); i++) { +                            /* Yes, we could optimize a little here */ +                         +                            if (try_rates[i] > r) { +                                r = try_rates[i]; +                                break;  +                            } +                        } +                     +                     +                        if (i == SA_ELEMENTSOF(try_rates)) { +                            phase = 1; +                            r = s->pcm_attrs.rate; +                        } +                    } + +                    if (phase == 1) { +                        /* Find the next lower sample rate to try */ + +                        for (i = SA_ELEMENTSOF(try_rates); i > 0; i--) { +                            if (suggested > try_rates[i-1] && suggested < r) { +                                r = suggested; +                                break; +                            } else if (try_rates[i-1] < r) { +                                r = try_rates[i-1]; +                                break; +                            } +                        } +                     +                        sa_assert(i > 0); +                    } +                 +                } else { + +                    if (phase == 0) { +                        /* Find the next lower sample rate to try */ + +                        for (i = SA_ELEMENTSOF(try_rates); i > 0; i--) { +                         +                            if (try_rates[i-1] < r) { +                                r = try_rates[i-1]; +                                break;  +                            } +                        } +                     +                        if (i == 0) { +                            phase = 1; +                            r = s->pcm_attrs.rate; +                        } +                    } + +                    if (phase == 1) { +                        /* Find the next higher sample rate to try */ + +                        for (i = 0; i < (int) SA_ELEMENTSOF(try_rates); i++) { +                            if (suggested > r && suggested < try_rates[i]) { +                                r = suggested; +                                break; +                            } else if (try_rates[i] < r) { +                                r = try_rates[i]; +                                break; +                            } +                        } +                     +                        sa_assert(i < (int) SA_ELEMENTSOF(try_rates)); +                    } +                } + +            } + +            oss->real_pcm_attrs.rate = r; + +            printf("Chosen: %u channels, %uHz, format=%u\n", oss->real_pcm_attrs.nchannels, oss->real_pcm_attrs.rate, oss->real_pcm_attrs.format); + +            real_bps = oss->real_pcm_attrs.nchannels * oss->real_pcm_attrs.rate * sa_get_pcm_sample_size(oss->real_pcm_attrs.format); + +            if (real_bps != bps && loops < 1) { +                loops++; + +                sa_free(oss->real_pcm_attrs.channel_map); +                oss->real_pcm_attrs.channel_map = NULL; + +                close(oss->fd); + +                printf("bps changed, retrying...\n"); +                continue; +            } +        } + +        break; +    } + +    /* First, let's try GETBLKSIZE */ +    if (ioctl(oss->fd, SNDCTL_DSP_GETBLKSIZE, &arg) >= 0) { +        if (s->mode & SA_MODE_RDONLY) { +            oss->read_fragment_size = arg; +            oss->read_nfragments = 2; +        } +         +        if (s->mode & SA_MODE_WRONLY) { +            oss->write_fragment_size = arg; +            oss->write_nfragments = 2; +        } +    } +     +    /* Now, let's use GETxSPACE */ +    if (s->mode & SA_MODE_RDONLY) { +        audio_buf_info info; +         +        if (ioctl(oss->fd, SNDCTL_DSP_GETISPACE, &info) >= 0) { +            oss->read_fragment_size = info.fragsize; +            oss->read_nfragments = info.fragstotal; +        } +    } +     +    if (s->mode & SA_MODE_WRONLY) { +        audio_buf_info info; +         +        if (ioctl(oss->fd, SNDCTL_DSP_GETOSPACE, &info) >= 0) { +            oss->write_fragment_size = info.fragsize; +            oss->write_nfragments = info.fragstotal; +        } +    } +     +    if (s->mode & SA_MODE_WRONLY && (oss->write_fragment_size <= 0 || oss->write_nfragments <= 1)) { +        errno = EIO; +        r = SA_ERROR_SYSTEM; +        goto fail; +    } +     +    if (s->mode & SA_MODE_RDONLY && (oss->read_fragment_size <= 0 || oss->read_nfragments <= 1)) { +        errno = EIO; +        r = SA_ERROR_SYSTEM; +        goto fail; +    } + +    if (!s->codec) { +         +        if (s->adjust_nchannels != 0) { +            sa_channel_t *cm; + +            if (!(cm = sa_newdup(sa_channel_t, oss->real_pcm_attrs.channel_map, oss->real_pcm_attrs.nchannels))) { +                r = SA_ERROR_OOM; +                goto fail; +            } + +            sa_free(s->pcm_attrs.channel_map); +            s->pcm_attrs.channel_map = cm; + +            s->pcm_attrs.nchannels = oss->real_pcm_attrs.nchannels; +        } +        if (s->adjust_rate != 0) +            s->pcm_attrs.rate = oss->real_pcm_attrs.rate; +        if (s->adjust_pcm_format != 0) +            s->pcm_attrs.format = oss->real_pcm_attrs.format; + +        if (s->mode & SA_MODE_RDONLY) +            if ((r = sa_converter_init(&oss->converter_read, &oss->real_pcm_attrs, &s->pcm_attrs, s->dynamic_rate_enabled)) < 0) +                goto fail; +         +        if (s->mode & SA_MODE_WRONLY) +            if ((r = sa_converter_init(&oss->converter_write, &s->pcm_attrs, &oss->real_pcm_attrs, s->dynamic_rate_enabled)) < 0) +                goto fail; +    } + +    if (s->adjust_watermarks) { + +        if (s->mode & SA_MODE_RDONLY) { +            s->read_lower_watermark = oss->read_fragment_size; +            s->read_upper_watermark = oss->read_fragment_size * oss->read_nfragments; +        } + +        if (s->mode & SA_MODE_WRONLY) { +            s->write_lower_watermark = oss->write_fragment_size; +            s->write_upper_watermark = oss->write_fragment_size * oss->write_nfragments; +        } +    } +     +    if (s->mode & SA_MODE_RDONLY) +        printf("Chosen for read: %u fragments, %u fragsize\n", oss->read_nfragments, oss->read_fragment_size); + +    if (s->mode & SA_MODE_WRONLY) +        printf("Chosen for write: %u fragments, %u fragsize\n", oss->write_nfragments, oss->write_fragment_size); + +    if (sa_bufferq_init(&oss->bufferq, s->pcm_attrs.nchannels, s->pcm_sample_size) < 0) +        goto fail; +     +    return SA_SUCCESS; + +fail: +    driver_destroy(s); +    return r; +} + +int driver_destroy(sa_stream_t *s) { +    oss_stream_t *oss = OSS_STREAM(s); + +    if (oss) { + +        if (oss->thread) +            driver_stop_thread(s); +         +        if (oss->fd >= 0) +            close(oss->fd); +         +        sa_bufferq_done(&oss->bufferq); +         +        sa_free(oss->real_pcm_attrs.channel_map); +        sa_converter_done(&oss->converter_read); +        sa_converter_done(&oss->converter_write); + +        sa_free(oss); +    } +     +    return SA_SUCCESS; +} + +static int feed(sa_stream_t *s) { +    oss_stream_t *oss = OSS_STREAM(s); +    size_t w; +    int ret; +     +    sa_assert(s); + +    for (;;) { +        if ((ret = driver_get_write_size(s, &w)) < 0) +            return ret; + +        while (w > 0) { +            void* i[1]; +            size_t nbytes; +            uint8_t *d; +            int drop; + +            sa_bufferq_get(&oss->bufferq, i, &nbytes); + +            if (nbytes) { +                void **dst; +                size_t *stride; + +                if ((ret = sa_converter_go_interleaved(&oss->converter_write, i[0], &dst, &stride, 1, &nbytes))) +                    return ret; + +                d = dst[0]; +                drop = 1; + +                s->state = SA_STATE_RUNNING; +                 +            } else { +                nbytes = w > oss->write_fragment_size ? oss->write_fragment_size : w; +                 +                if (!(d = sa_converter_get_zero_buffer(&oss->converter_write, nbytes))) +                    return SA_ERROR_OOM; + +                drop = s->xrun_mode == SA_XRUN_MODE_SPIN; + +                if (s->xrun_mode == SA_XRUN_MODE_STOP) +                    s->state = SA_STATE_STOPPED; +            } + +            while (nbytes > 0) { +                ssize_t l; +                 +                if ((l = write(oss->fd, d, nbytes)) < 0) +                    return SA_ERROR_SYSTEM; +                 +                sa_assert(l > 0); +                 +                nbytes -= l; +                d += l; + +                w -= 1; +                 +                if (drop) +                    sa_bufferq_drop(&oss->bufferq, l); +            } +        } +    } + +    return SA_SUCCESS; +} + +enum { +    POLLFD_OSS_FD, +    POLLFD_SOCKET_FD, +    POLLFD_MAX +}; + +static void thread_func(void *data) { +    struct pollfd pollfds[POLLFD_MAX]; +    sa_stream_t *s = data; +    oss_stream_t *oss = OSS_STREAM(s); +    sigset_t mask; + +    sigfillset(&mask); +    pthread_sigmask(SIG_BLOCK, &mask, NULL); + +    if (s->callback) { +        s->event = SA_EVENT_INIT_THREAD; +        if (s->callback(s, SA_EVENT_INIT_THREAD) < 0) +            return; +    } +     +    memset(pollfds, 0, sizeof(pollfds)); + +    pollfds[POLLFD_SOCKET_FD].fd = oss->socket_fds[0]; +    pollfds[POLLFD_SOCKET_FD].events = POLLIN; +     +    pollfds[POLLFD_OSS_FD].fd = oss->fd; +    pollfds[POLLFD_OSS_FD].events = ((s->mode & SA_MODE_RDONLY) ? POLLIN : 0) | ((s->mode & SA_MODE_WRONLY) ? POLLOUT : 0); +     +    for (;;) { +        int ret; +        if (poll(pollfds, POLLFD_MAX, -1) < 0) { +            if (errno == EINTR) +                continue; + +            if (s->callback) { +                s->event = SA_EVENT_ERROR; +                s->error = SA_ERROR_SYSTEM; +                s->callback(s, SA_EVENT_ERROR); +            } +            break; +        } + +        if (pollfds[POLLFD_SOCKET_FD].revents) +            break; + +        if (pollfds[POLLFD_OSS_FD].revents & (POLLERR|POLLHUP|POLLNVAL)) { + +            if (s->callback) { +                s->event = SA_EVENT_ERROR; +                s->error = SA_ERROR_SYSTEM; +                errno = EIO; +                s->callback(s, SA_EVENT_ERROR); +            } +            break; +        } + +        if (s->callback) { +            s->event = SA_EVENT_REQUEST_IO; +            if (s->callback(s, SA_EVENT_REQUEST_IO) < 0) +                break; +        } + +        if ((ret = feed(s)) < 0) { +            if (s->callback) { +                s->event = SA_EVENT_ERROR; +                s->error = ret; +                s->callback(s, SA_EVENT_ERROR); +            } +            break; +        } +    } +} + +int driver_start_thread(sa_stream_t *s, sa_event_callback_t callback) { +    oss_stream_t *oss = OSS_STREAM(s); +    sa_return_val_if_fail(!oss->thread, SA_ERROR_STATE); + +    s->callback = callback; + +    if ((socketpair(AF_UNIX, SOCK_DGRAM, 0, oss->socket_fds)) < 0) +        return SA_ERROR_SYSTEM; + +    if (!(oss->thread = sa_thread_new(thread_func, s))) +        return SA_ERROR_OOM; +     +    return SA_SUCCESS; +} + +int driver_stop_thread(sa_stream_t *s) { +    oss_stream_t *oss = OSS_STREAM(s); +    sa_return_val_if_fail(oss->thread, SA_ERROR_STATE); +    sa_return_val_if_fail(oss->thread != sa_thread_self(), SA_ERROR_STATE); + +    if (oss->socket_fds[0] >= 0) +        close(oss->socket_fds[0]); +     +    if (oss->socket_fds[1] >= 0) +        close(oss->socket_fds[1]); +     +    if (oss->thread) +        sa_thread_free(oss->thread); +     +    oss->thread = NULL; +    oss->socket_fds[0] = oss->socket_fds[1] = -1; + +    return SA_SUCCESS; +} + +int driver_change_read_volume(sa_stream_t *s, const int32_t vol[]) { +    oss_stream_t *oss = OSS_STREAM(s); + +    sa_return_val_if_fail(!s->codec, SA_ERROR_NOT_SUPPORTED); + +    sa_converter_set_volume(&oss->converter_read, vol); +     +    return SA_SUCCESS; +} + +int driver_change_write_volume(sa_stream_t *s, const int32_t vol[]) { +    oss_stream_t *oss = OSS_STREAM(s); + +    sa_return_val_if_fail(!s->codec, SA_ERROR_NOT_SUPPORTED); + +    sa_converter_set_volume(&oss->converter_write, vol); +     +    return SA_SUCCESS; +} + +int driver_change_rate(sa_stream_t *s, unsigned rate) { +    oss_stream_t *oss = OSS_STREAM(s); + +    if (s->mode & SA_MODE_RDONLY) +        sa_converter_set_ratio(&oss->converter_read, oss->real_pcm_attrs.rate, s->pcm_attrs.rate); +    if (s->mode & SA_MODE_WRONLY) +        sa_converter_set_ratio(&oss->converter_write, s->pcm_attrs.rate, oss->real_pcm_attrs.rate); + +    return SA_SUCCESS; +} + +int driver_get_state(sa_stream_t *s, sa_state_t *state) { +    *state = s->state; +    return SA_SUCCESS; +} + +int driver_get_position(sa_stream_t *s, sa_position_t position, int64_t *pos) { +    return SA_ERROR_NOT_SUPPORTED; +} + +int driver_read(sa_stream_t *s, void *data, size_t nbytes) { +    return SA_ERROR_NOT_SUPPORTED; +} + +int driver_pwrite(sa_stream_t *s, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence) { +    oss_stream_t *oss = OSS_STREAM(s); +    int ret, ret2; + +    if ((ret = sa_bufferq_push(&oss->bufferq, 0, data, nbytes, offset, whence, SA_BUFFERQ_ITEM_STATIC))) +        return ret; +     +    ret = feed(s); +    ret2 = sa_bufferq_realloc(&oss->bufferq); + +    return ret ? ret : ret2; +} + +int driver_read_ni(sa_stream_t *s, unsigned channel, void *data, size_t nbytes) { +    return SA_ERROR_NOT_SUPPORTED; +} + +int driver_pwrite_ni(sa_stream_t *s, unsigned channel, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence) { +    return SA_ERROR_NOT_SUPPORTED; +} + +int driver_get_read_size(sa_stream_t *s, size_t *size) { +    return SA_ERROR_NOT_SUPPORTED; +} + +int driver_get_write_size(sa_stream_t *s, size_t *size)  { +    return SA_ERROR_NOT_SUPPORTED; +} + +int driver_resume(sa_stream_t *s) { +    return SA_ERROR_NOT_SUPPORTED; +} + +int driver_pause(sa_stream_t *s) { +    return SA_ERROR_NOT_SUPPORTED; +} + +int driver_drain(sa_stream_t *s) { +    oss_stream_t *oss = OSS_STREAM(s); +    sa_return_val_if_fail(!oss->thread, SA_ERROR_STATE); + +    if (ioctl(oss->fd, SNDCTL_DSP_SYNC, NULL) < 0) +        return SA_ERROR_SYSTEM; +     +    return SA_SUCCESS; +} + +/* Unsupported operations */ + +int driver_change_device(sa_stream_t *s, const char *device) { +    return SA_ERROR_NOT_SUPPORTED; +} + +int driver_change_meta_data(sa_stream_t *s, const char *name, const void *data, size_t size) { +    return SA_ERROR_NOT_SUPPORTED; +} diff --git a/src/resample.c b/src/resample.c new file mode 100644 index 0000000..23c63a5 --- /dev/null +++ b/src/resample.c @@ -0,0 +1,42 @@ +#include "macro.h" +#include "resample.h" + +static void resample_s16(SpeexResamplerState *speex, unsigned channel, void *dst, size_t dstr, const void *src, size_t sstr, size_t in_bytes, size_t *out_bytes) { + +    spx_uint32_t in_samples = in_bytes/sizeof(int16_t), out_samples = *out_bytes/sizeof(int16_t); +     +    speex_resampler_set_input_stride(speex, sstr/sizeof(int16_t)); +    speex_resampler_set_input_stride(speex, dstr/sizeof(int16_t)); + +    speex_resampler_process_int(speex, channel, src, &in_samples, dst, &out_samples); + +    sa_assert(in_samples == in_bytes/sizeof(int16_t)); + +    *out_bytes = out_samples * sizeof(int16_t); +} + +static void resample_f32(SpeexResamplerState *speex, unsigned channel, void *dst, size_t dstr, const void *src, size_t sstr, size_t in_bytes, size_t *out_bytes) { + +    spx_uint32_t in_samples = in_bytes/sizeof(float), out_samples = *out_bytes/sizeof(float); +     +    speex_resampler_set_input_stride(speex, sstr/sizeof(float)); +    speex_resampler_set_input_stride(speex, dstr/sizeof(float)); + +    speex_resampler_process_float(speex, channel, src, &in_samples, dst, &out_samples); + +    sa_assert(in_samples == in_bytes/sizeof(float)); + +    *out_bytes = out_samples * sizeof(float); +} + +sa_resample_func_t sa_get_resample_func(sa_pcm_format_t f) { + +    static const sa_resample_func_t funcs[_SA_PCM_FORMAT_MAX] = { +        [SA_PCM_FORMAT_S16_NE] = resample_s16, +        [SA_PCM_FORMAT_FLOAT32_NE] = resample_f32 +    }; + +    sa_assert(f < _SA_PCM_FORMAT_MAX); + +    return funcs[f]; +} diff --git a/src/resample.h b/src/resample.h new file mode 100644 index 0000000..7734f86 --- /dev/null +++ b/src/resample.h @@ -0,0 +1,14 @@ +#ifndef foosydneyresamplehfoo +#define foosydneyresamplehfoo + +#include <sys/types.h> +#include <inttypes.h> + +#include "sydney.h" +#include "speex/speex_resampler.h" + +typedef void (*sa_resample_func_t) (SpeexResamplerState *speex, unsigned channel, void *dst, size_t dstr, const void *src, size_t sstr, size_t in_bytes, size_t *out_bytes); + +sa_resample_func_t sa_get_resample_func(sa_pcm_format_t f); + +#endif diff --git a/src/speex/arch.h b/src/speex/arch.h new file mode 100644 index 0000000..e2d731a --- /dev/null +++ b/src/speex/arch.h @@ -0,0 +1,197 @@ +/* Copyright (C) 2003 Jean-Marc Valin */ +/** +   @file arch.h +   @brief Various architecture definitions Speex +*/ +/* +   Redistribution and use in source and binary forms, with or without +   modification, are permitted provided that the following conditions +   are met: +    +   - Redistributions of source code must retain the above copyright +   notice, this list of conditions and the following disclaimer. +    +   - Redistributions in binary form must reproduce the above copyright +   notice, this list of conditions and the following disclaimer in the +   documentation and/or other materials provided with the distribution. +    +   - Neither the name of the Xiph.org Foundation nor the names of its +   contributors may be used to endorse or promote products derived from +   this software without specific prior written permission. +    +   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR +   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef ARCH_H +#define ARCH_H + +#ifndef OUTSIDE_SPEEX +#include "speex/speex_types.h" +#endif + +#define ABS(x) ((x) < 0 ? (-(x)) : (x))      /**< Absolute integer value. */ +#define ABS16(x) ((x) < 0 ? (-(x)) : (x))    /**< Absolute 16-bit value.  */ +#define MIN16(a,b) ((a) < (b) ? (a) : (b))   /**< Maximum 16-bit value.   */ +#define MAX16(a,b) ((a) > (b) ? (a) : (b))   /**< Maximum 16-bit value.   */ +#define ABS32(x) ((x) < 0 ? (-(x)) : (x))    /**< Absolute 32-bit value.  */ +#define MIN32(a,b) ((a) < (b) ? (a) : (b))   /**< Maximum 32-bit value.   */ +#define MAX32(a,b) ((a) > (b) ? (a) : (b))   /**< Maximum 32-bit value.   */ + +#ifdef FIXED_POINT + +typedef spx_int16_t spx_word16_t; +typedef spx_int32_t   spx_word32_t; +typedef spx_word32_t spx_mem_t; +typedef spx_word16_t spx_coef_t; +typedef spx_word16_t spx_lsp_t; +typedef spx_word32_t spx_sig_t; + +#define Q15ONE 32767 + +#define LPC_SCALING  8192 +#define SIG_SCALING  16384 +#define LSP_SCALING  8192. +#define GAMMA_SCALING 32768. +#define GAIN_SCALING 64 +#define GAIN_SCALING_1 0.015625 + +#define LPC_SHIFT    13 +#define LSP_SHIFT    13 +#define SIG_SHIFT    14 + +#define VERY_SMALL 0 +#define VERY_LARGE32 ((spx_word32_t)2147483647) +#define VERY_LARGE16 ((spx_word16_t)32767) +#define Q15_ONE ((spx_word16_t)32767) + + +#ifdef FIXED_DEBUG +#include "fixed_debug.h" +#else + +#include "fixed_generic.h" + +#ifdef ARM5E_ASM +#include "fixed_arm5e.h" +#elif defined (ARM4_ASM) +#include "fixed_arm4.h" +#elif defined (ARM5E_ASM) +#include "fixed_arm5e.h" +#elif defined (BFIN_ASM) +#include "fixed_bfin.h" +#endif + +#endif + + +#else + +typedef float spx_mem_t; +typedef float spx_coef_t; +typedef float spx_lsp_t; +typedef float spx_sig_t; +typedef float spx_word16_t; +typedef float spx_word32_t; + +#define Q15ONE 1.0f +#define LPC_SCALING  1.f +#define SIG_SCALING  1.f +#define LSP_SCALING  1.f +#define GAMMA_SCALING 1.f +#define GAIN_SCALING 1.f +#define GAIN_SCALING_1 1.f + +#define LPC_SHIFT    0 +#define LSP_SHIFT    0 +#define SIG_SHIFT    0 + +#define VERY_SMALL 1e-15f +#define VERY_LARGE32 1e15f +#define VERY_LARGE16 1e15f +#define Q15_ONE ((spx_word16_t)1.f) + +#define QCONST16(x,bits) (x) +#define QCONST32(x,bits) (x) + +#define NEG16(x) (-(x)) +#define NEG32(x) (-(x)) +#define EXTRACT16(x) (x) +#define EXTEND32(x) (x) +#define SHR16(a,shift) (a) +#define SHL16(a,shift) (a) +#define SHR32(a,shift) (a) +#define SHL32(a,shift) (a) +#define PSHR16(a,shift) (a) +#define PSHR32(a,shift) (a) +#define VSHR32(a,shift) (a) +#define SATURATE16(x,a) (x) +#define SATURATE32(x,a) (x) + +#define PSHR(a,shift)       (a) +#define SHR(a,shift)       (a) +#define SHL(a,shift)       (a) +#define SATURATE(x,a) (x) + +#define ADD16(a,b) ((a)+(b)) +#define SUB16(a,b) ((a)-(b)) +#define ADD32(a,b) ((a)+(b)) +#define SUB32(a,b) ((a)-(b)) +#define MULT16_16_16(a,b)     ((a)*(b)) +#define MULT16_16(a,b)     ((spx_word32_t)(a)*(spx_word32_t)(b)) +#define MAC16_16(c,a,b)     ((c)+(spx_word32_t)(a)*(spx_word32_t)(b)) + +#define MULT16_32_Q11(a,b)     ((a)*(b)) +#define MULT16_32_Q13(a,b)     ((a)*(b)) +#define MULT16_32_Q14(a,b)     ((a)*(b)) +#define MULT16_32_Q15(a,b)     ((a)*(b)) +#define MULT16_32_P15(a,b)     ((a)*(b)) + +#define MAC16_32_Q11(c,a,b)     ((c)+(a)*(b)) +#define MAC16_32_Q15(c,a,b)     ((c)+(a)*(b)) + +#define MAC16_16_Q11(c,a,b)     ((c)+(a)*(b)) +#define MAC16_16_Q13(c,a,b)     ((c)+(a)*(b)) +#define MAC16_16_P13(c,a,b)     ((c)+(a)*(b)) +#define MULT16_16_Q11_32(a,b)     ((a)*(b)) +#define MULT16_16_Q13(a,b)     ((a)*(b)) +#define MULT16_16_Q14(a,b)     ((a)*(b)) +#define MULT16_16_Q15(a,b)     ((a)*(b)) +#define MULT16_16_P15(a,b)     ((a)*(b)) +#define MULT16_16_P13(a,b)     ((a)*(b)) +#define MULT16_16_P14(a,b)     ((a)*(b)) + +#define DIV32_16(a,b)     (((spx_word32_t)(a))/(spx_word16_t)(b)) +#define PDIV32_16(a,b)     (((spx_word32_t)(a))/(spx_word16_t)(b)) +#define DIV32(a,b)     (((spx_word32_t)(a))/(spx_word32_t)(b)) +#define PDIV32(a,b)     (((spx_word32_t)(a))/(spx_word32_t)(b)) + + +#endif + + +#if defined (CONFIG_TI_C54X) || defined (CONFIG_TI_C55X) + +/* 2 on TI C5x DSP */ +#define BYTES_PER_CHAR 2  +#define BITS_PER_CHAR 16 +#define LOG2_BITS_PER_CHAR 4 + +#else  + +#define BYTES_PER_CHAR 1 +#define BITS_PER_CHAR 8 +#define LOG2_BITS_PER_CHAR 3 + +#endif + +#endif diff --git a/src/speex/resample.c b/src/speex/resample.c new file mode 100644 index 0000000..1cc4d49 --- /dev/null +++ b/src/speex/resample.c @@ -0,0 +1,1114 @@ +/* Copyright (C) 2007 Jean-Marc Valin +       +   File: resample.c +   Arbitrary resampling code + +   Redistribution and use in source and binary forms, with or without +   modification, are permitted provided that the following conditions are +   met: + +   1. Redistributions of source code must retain the above copyright notice, +   this list of conditions and the following disclaimer. + +   2. Redistributions in binary form must reproduce the above copyright +   notice, this list of conditions and the following disclaimer in the +   documentation and/or other materials provided with the distribution. + +   3. The name of the author may not be used to endorse or promote products +   derived from this software without specific prior written permission. + +   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +   IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +   DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +   POSSIBILITY OF SUCH DAMAGE. +*/ + +/* +   The design goals of this code are: +      - Very fast algorithm +      - SIMD-friendly algorithm +      - Low memory requirement +      - Good *perceptual* quality (and not best SNR) + +   The code is working, but it's in a very early stage, so it may have +   artifacts, noise or subliminal messages from satan. Also, the API  +   isn't stable and I can actually promise that I *will* change the API +   some time in the future. + +TODO list: +      - Variable calculation resolution depending on quality setting +         - Single vs double in float mode +         - 16-bit vs 32-bit (sinc only) in fixed-point mode +      - Make sure the filter update works even when changing params  +             after only a few samples procesed +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef OUTSIDE_SPEEX +#include <stdlib.h> +static void *speex_alloc (int size) {return calloc(size,1);} +static void *speex_realloc (void *ptr, int size) {return realloc(ptr, size);} +static void speex_free (void *ptr) {free(ptr);} +#include "speex_resampler.h" +#include "arch.h" +#else /* OUTSIDE_SPEEX */ +                +#include "speex/speex_resampler.h" +#include "misc.h" +#endif /* OUTSIDE_SPEEX */ + +#include <math.h> + +#ifndef M_PI +#define M_PI 3.14159263 +#endif + +#ifdef FIXED_POINT +#define WORD2INT(x) ((x) < -32767 ? -32768 : ((x) > 32766 ? 32767 : (x)))   +#else +#define WORD2INT(x) ((x) < -32767.5f ? -32768 : ((x) > 32766.5f ? 32767 : floor(.5+(x))))   +#endif +                +/*#define float double*/ +#define FILTER_SIZE 64 +#define OVERSAMPLE 8 + +#define IMAX(a,b) ((a) > (b) ? (a) : (b)) +#define IMIN(a,b) ((a) < (b) ? (a) : (b)) + +#ifndef NULL +#define NULL 0 +#endif + +typedef int (*resampler_basic_func)(SpeexResamplerState *, spx_uint32_t , const spx_word16_t *, spx_uint32_t *, spx_word16_t *, spx_uint32_t *); + +struct SpeexResamplerState_ { +   spx_uint32_t in_rate; +   spx_uint32_t out_rate; +   spx_uint32_t num_rate; +   spx_uint32_t den_rate; +    +   int    quality; +   spx_uint32_t nb_channels; +   spx_uint32_t filt_len; +   spx_uint32_t mem_alloc_size; +   int          int_advance; +   int          frac_advance; +   float  cutoff; +   spx_uint32_t oversample; +   int          initialised; +   int          started; +    +   /* These are per-channel */ +   spx_int32_t  *last_sample; +   spx_uint32_t *samp_frac_num; +   spx_uint32_t *magic_samples; +    +   spx_word16_t *mem; +   spx_word16_t *sinc_table; +   spx_uint32_t sinc_table_length; +   resampler_basic_func resampler_ptr; +          +   int    in_stride; +   int    out_stride; +} ; + +static double kaiser12_table[68] = { +   0.99859849, 1.00000000, 0.99859849, 0.99440475, 0.98745105, 0.97779076, +   0.96549770, 0.95066529, 0.93340547, 0.91384741, 0.89213598, 0.86843014, +   0.84290116, 0.81573067, 0.78710866, 0.75723148, 0.72629970, 0.69451601, +   0.66208321, 0.62920216, 0.59606986, 0.56287762, 0.52980938, 0.49704014, +   0.46473455, 0.43304576, 0.40211431, 0.37206735, 0.34301800, 0.31506490, +   0.28829195, 0.26276832, 0.23854851, 0.21567274, 0.19416736, 0.17404546, +   0.15530766, 0.13794294, 0.12192957, 0.10723616, 0.09382272, 0.08164178, +   0.07063950, 0.06075685, 0.05193064, 0.04409466, 0.03718069, 0.03111947, +   0.02584161, 0.02127838, 0.01736250, 0.01402878, 0.01121463, 0.00886058, +   0.00691064, 0.00531256, 0.00401805, 0.00298291, 0.00216702, 0.00153438, +   0.00105297, 0.00069463, 0.00043489, 0.00025272, 0.00013031, 0.0000527734, +   0.00001000, 0.00000000}; +/* +static double kaiser12_table[36] = { +   0.99440475, 1.00000000, 0.99440475, 0.97779076, 0.95066529, 0.91384741, +   0.86843014, 0.81573067, 0.75723148, 0.69451601, 0.62920216, 0.56287762, +   0.49704014, 0.43304576, 0.37206735, 0.31506490, 0.26276832, 0.21567274, +   0.17404546, 0.13794294, 0.10723616, 0.08164178, 0.06075685, 0.04409466, +   0.03111947, 0.02127838, 0.01402878, 0.00886058, 0.00531256, 0.00298291, +   0.00153438, 0.00069463, 0.00025272, 0.0000527734, 0.00000500, 0.00000000}; +*/ +static double kaiser10_table[36] = { +   0.99537781, 1.00000000, 0.99537781, 0.98162644, 0.95908712, 0.92831446, +   0.89005583, 0.84522401, 0.79486424, 0.74011713, 0.68217934, 0.62226347, +   0.56155915, 0.50119680, 0.44221549, 0.38553619, 0.33194107, 0.28205962, +   0.23636152, 0.19515633, 0.15859932, 0.12670280, 0.09935205, 0.07632451, +   0.05731132, 0.04193980, 0.02979584, 0.02044510, 0.01345224, 0.00839739, +   0.00488951, 0.00257636, 0.00115101, 0.00035515, 0.00000000, 0.00000000}; + +static double kaiser8_table[36] = { +   0.99635258, 1.00000000, 0.99635258, 0.98548012, 0.96759014, 0.94302200, +   0.91223751, 0.87580811, 0.83439927, 0.78875245, 0.73966538, 0.68797126, +   0.63451750, 0.58014482, 0.52566725, 0.47185369, 0.41941150, 0.36897272, +   0.32108304, 0.27619388, 0.23465776, 0.19672670, 0.16255380, 0.13219758, +   0.10562887, 0.08273982, 0.06335451, 0.04724088, 0.03412321, 0.02369490, +   0.01563093, 0.00959968, 0.00527363, 0.00233883, 0.00050000, 0.00000000}; +    +static double kaiser6_table[36] = { +   0.99733006, 1.00000000, 0.99733006, 0.98935595, 0.97618418, 0.95799003, +   0.93501423, 0.90755855, 0.87598009, 0.84068475, 0.80211977, 0.76076565, +   0.71712752, 0.67172623, 0.62508937, 0.57774224, 0.53019925, 0.48295561, +   0.43647969, 0.39120616, 0.34752997, 0.30580127, 0.26632152, 0.22934058, +   0.19505503, 0.16360756, 0.13508755, 0.10953262, 0.08693120, 0.06722600, +   0.05031820, 0.03607231, 0.02432151, 0.01487334, 0.00752000, 0.00000000}; + +struct FuncDef { +   double *table; +   int oversample; +}; +       +static struct FuncDef _KAISER12 = {kaiser12_table, 64}; +#define KAISER12 (&_KAISER12) +/*static struct FuncDef _KAISER12 = {kaiser12_table, 32}; +#define KAISER12 (&_KAISER12)*/ +static struct FuncDef _KAISER10 = {kaiser10_table, 32}; +#define KAISER10 (&_KAISER10) +static struct FuncDef _KAISER8 = {kaiser8_table, 32}; +#define KAISER8 (&_KAISER8) +static struct FuncDef _KAISER6 = {kaiser6_table, 32}; +#define KAISER6 (&_KAISER6) + +struct QualityMapping { +   int base_length; +   int oversample; +   float downsample_bandwidth; +   float upsample_bandwidth; +   struct FuncDef *window_func; +}; + + +/* This table maps conversion quality to internal parameters. There are two +   reasons that explain why the up-sampling bandwidth is larger than the  +   down-sampling bandwidth: +   1) When up-sampling, we can assume that the spectrum is already attenuated +      close to the Nyquist rate (from an A/D or a previous resampling filter) +   2) Any aliasing that occurs very close to the Nyquist rate will be masked +      by the sinusoids/noise just below the Nyquist rate (guaranteed only for +      up-sampling). +*/ +static const struct QualityMapping quality_map[11] = { +   {  8,  4, 0.830f, 0.860f, KAISER6 }, /* Q0 */ +   { 16,  4, 0.850f, 0.880f, KAISER6 }, /* Q1 */ +   { 32,  4, 0.882f, 0.910f, KAISER6 }, /* Q2 */  /* 82.3% cutoff ( ~60 dB stop) 6  */ +   { 48,  8, 0.895f, 0.917f, KAISER8 }, /* Q3 */  /* 84.9% cutoff ( ~80 dB stop) 8  */ +   { 64,  8, 0.921f, 0.940f, KAISER8 }, /* Q4 */  /* 88.7% cutoff ( ~80 dB stop) 8  */ +   { 80, 16, 0.922f, 0.940f, KAISER10}, /* Q5 */  /* 89.1% cutoff (~100 dB stop) 10 */ +   { 96, 16, 0.940f, 0.945f, KAISER10}, /* Q6 */  /* 91.5% cutoff (~100 dB stop) 10 */ +   {128, 16, 0.950f, 0.950f, KAISER10}, /* Q7 */  /* 93.1% cutoff (~100 dB stop) 10 */ +   {160, 16, 0.960f, 0.960f, KAISER10}, /* Q8 */  /* 94.5% cutoff (~100 dB stop) 10 */ +   {192, 32, 0.968f, 0.968f, KAISER12}, /* Q9 */  /* 95.5% cutoff (~100 dB stop) 10 */ +   {256, 32, 0.975f, 0.975f, KAISER12}, /* Q10 */ /* 96.6% cutoff (~100 dB stop) 10 */ +}; +/*8,24,40,56,80,104,128,160,200,256,320*/ +static double compute_func(float x, struct FuncDef *func) +{ +   float y, frac; +   double interp[4]; +   int ind;  +   y = x*func->oversample; +   ind = (int)floor(y); +   frac = (y-ind); +   /* CSE with handle the repeated powers */ +   interp[3] =  -0.1666666667*frac + 0.1666666667*(frac*frac*frac); +   interp[2] = frac + 0.5*(frac*frac) - 0.5*(frac*frac*frac); +   /*interp[2] = 1.f - 0.5f*frac - frac*frac + 0.5f*frac*frac*frac;*/ +   interp[0] = -0.3333333333*frac + 0.5*(frac*frac) - 0.1666666667*(frac*frac*frac); +   /* Just to make sure we don't have rounding problems */ +   interp[1] = 1.f-interp[3]-interp[2]-interp[0]; +    +   /*sum = frac*accum[1] + (1-frac)*accum[2];*/ +   return interp[0]*func->table[ind] + interp[1]*func->table[ind+1] + interp[2]*func->table[ind+2] + interp[3]*func->table[ind+3]; +} + +#if 0 +#include <stdio.h> +int main(int argc, char **argv) +{ +   int i; +   for (i=0;i<256;i++) +   { +      printf ("%f\n", compute_func(i/256., KAISER12)); +   } +   return 0; +} +#endif + +#ifdef FIXED_POINT +/* The slow way of computing a sinc for the table. Should improve that some day */ +static spx_word16_t sinc(float cutoff, float x, int N, struct FuncDef *window_func) +{ +   /*fprintf (stderr, "%f ", x);*/ +   float xx = x * cutoff; +   if (fabs(x)<1e-6f) +      return WORD2INT(32768.*cutoff); +   else if (fabs(x) > .5f*N) +      return 0; +   /*FIXME: Can it really be any slower than this? */ +   return WORD2INT(32768.*cutoff*sin(M_PI*xx)/(M_PI*xx) * compute_func(fabs(2.*x/N), window_func)); +} +#else +/* The slow way of computing a sinc for the table. Should improve that some day */ +static spx_word16_t sinc(float cutoff, float x, int N, struct FuncDef *window_func) +{ +   /*fprintf (stderr, "%f ", x);*/ +   float xx = x * cutoff; +   if (fabs(x)<1e-6) +      return cutoff; +   else if (fabs(x) > .5*N) +      return 0; +   /*FIXME: Can it really be any slower than this? */ +   return cutoff*sin(M_PI*xx)/(M_PI*xx) * compute_func(fabs(2.*x/N), window_func); +} +#endif + +#ifdef FIXED_POINT +static void cubic_coef(spx_word16_t x, spx_word16_t interp[4]) +{ +   /* Compute interpolation coefficients. I'm not sure whether this corresponds to cubic interpolation +   but I know it's MMSE-optimal on a sinc */ +   spx_word16_t x2, x3; +   x2 = MULT16_16_P15(x, x); +   x3 = MULT16_16_P15(x, x2); +   interp[0] = PSHR32(MULT16_16(QCONST16(-0.16667f, 15),x) + MULT16_16(QCONST16(0.16667f, 15),x3),15); +   interp[1] = EXTRACT16(EXTEND32(x) + SHR32(SUB32(EXTEND32(x2),EXTEND32(x3)),1)); +   interp[3] = PSHR32(MULT16_16(QCONST16(-0.33333f, 15),x) + MULT16_16(QCONST16(.5f,15),x2) - MULT16_16(QCONST16(0.16667f, 15),x3),15); +   /* Just to make sure we don't have rounding problems */ +   interp[2] = Q15_ONE-interp[0]-interp[1]-interp[3]; +   if (interp[2]<32767) +      interp[2]+=1; +} +#else +static void cubic_coef(spx_word16_t frac, spx_word16_t interp[4]) +{ +   /* Compute interpolation coefficients. I'm not sure whether this corresponds to cubic interpolation +   but I know it's MMSE-optimal on a sinc */ +   interp[0] =  -0.16667f*frac + 0.16667f*frac*frac*frac; +   interp[1] = frac + 0.5f*frac*frac - 0.5f*frac*frac*frac; +   /*interp[2] = 1.f - 0.5f*frac - frac*frac + 0.5f*frac*frac*frac;*/ +   interp[3] = -0.33333f*frac + 0.5f*frac*frac - 0.16667f*frac*frac*frac; +   /* Just to make sure we don't have rounding problems */ +   interp[2] = 1.-interp[0]-interp[1]-interp[3]; +} +#endif + +static int resampler_basic_direct_single(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len) +{ +   int N = st->filt_len; +   int out_sample = 0; +   spx_word16_t *mem; +   int last_sample = st->last_sample[channel_index]; +   spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index]; +   mem = st->mem + channel_index * st->mem_alloc_size; +   while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len)) +   { +      int j; +      spx_word32_t sum=0; +       +      /* We already have all the filter coefficients pre-computed in the table */ +      const spx_word16_t *ptr; +      /* Do the memory part */ +      for (j=0;last_sample-N+1+j < 0;j++) +      { +         sum += MULT16_16(mem[last_sample+j],st->sinc_table[samp_frac_num*st->filt_len+j]); +      } +       +      /* Do the new part */ +      ptr = in+st->in_stride*(last_sample-N+1+j); +      for (;j<N;j++) +      { +         sum += MULT16_16(*ptr,st->sinc_table[samp_frac_num*st->filt_len+j]); +         ptr += st->in_stride; +      } +    +      *out = PSHR32(sum,15); +      out += st->out_stride; +      out_sample++; +      last_sample += st->int_advance; +      samp_frac_num += st->frac_advance; +      if (samp_frac_num >= st->den_rate) +      { +         samp_frac_num -= st->den_rate; +         last_sample++; +      } +   } +   st->last_sample[channel_index] = last_sample; +   st->samp_frac_num[channel_index] = samp_frac_num; +   return out_sample; +} + +#ifdef FIXED_POINT +#else +/* This is the same as the previous function, except with a double-precision accumulator */ +static int resampler_basic_direct_double(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len) +{ +   int N = st->filt_len; +   int out_sample = 0; +   spx_word16_t *mem; +   int last_sample = st->last_sample[channel_index]; +   spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index]; +   mem = st->mem + channel_index * st->mem_alloc_size; +   while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len)) +   { +      int j; +      double sum=0; +       +      /* We already have all the filter coefficients pre-computed in the table */ +      const spx_word16_t *ptr; +      /* Do the memory part */ +      for (j=0;last_sample-N+1+j < 0;j++) +      { +         sum += MULT16_16(mem[last_sample+j],(double)st->sinc_table[samp_frac_num*st->filt_len+j]); +      } +       +      /* Do the new part */ +      ptr = in+st->in_stride*(last_sample-N+1+j); +      for (;j<N;j++) +      { +         sum += MULT16_16(*ptr,(double)st->sinc_table[samp_frac_num*st->filt_len+j]); +         ptr += st->in_stride; +      } +    +      *out = sum; +      out += st->out_stride; +      out_sample++; +      last_sample += st->int_advance; +      samp_frac_num += st->frac_advance; +      if (samp_frac_num >= st->den_rate) +      { +         samp_frac_num -= st->den_rate; +         last_sample++; +      } +   } +   st->last_sample[channel_index] = last_sample; +   st->samp_frac_num[channel_index] = samp_frac_num; +   return out_sample; +} +#endif + +static int resampler_basic_interpolate_single(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len) +{ +   int N = st->filt_len; +   int out_sample = 0; +   spx_word16_t *mem; +   int last_sample = st->last_sample[channel_index]; +   spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index]; +   mem = st->mem + channel_index * st->mem_alloc_size; +   while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len)) +   { +      int j; +      spx_word32_t sum=0; +       +      /* We need to interpolate the sinc filter */ +      spx_word32_t accum[4] = {0.f,0.f, 0.f, 0.f}; +      spx_word16_t interp[4]; +      const spx_word16_t *ptr; +      int offset; +      spx_word16_t frac; +      offset = samp_frac_num*st->oversample/st->den_rate; +#ifdef FIXED_POINT +      frac = PDIV32(SHL32((samp_frac_num*st->oversample) % st->den_rate,15),st->den_rate); +#else +      frac = ((float)((samp_frac_num*st->oversample) % st->den_rate))/st->den_rate; +#endif +         /* This code is written like this to make it easy to optimise with SIMD. +      For most DSPs, it would be best to split the loops in two because most DSPs  +      have only two accumulators */ +      for (j=0;last_sample-N+1+j < 0;j++) +      { +         spx_word16_t curr_mem = mem[last_sample+j]; +         accum[0] += MULT16_16(curr_mem,st->sinc_table[4+(j+1)*st->oversample-offset-2]); +         accum[1] += MULT16_16(curr_mem,st->sinc_table[4+(j+1)*st->oversample-offset-1]); +         accum[2] += MULT16_16(curr_mem,st->sinc_table[4+(j+1)*st->oversample-offset]); +         accum[3] += MULT16_16(curr_mem,st->sinc_table[4+(j+1)*st->oversample-offset+1]); +      } +      ptr = in+st->in_stride*(last_sample-N+1+j); +      /* Do the new part */ +      for (;j<N;j++) +      { +         spx_word16_t curr_in = *ptr; +         ptr += st->in_stride; +         accum[0] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-2]); +         accum[1] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-1]); +         accum[2] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset]); +         accum[3] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset+1]); +      } +      cubic_coef(frac, interp); +      sum = MULT16_32_Q15(interp[0],accum[0]) + MULT16_32_Q15(interp[1],accum[1]) + MULT16_32_Q15(interp[2],accum[2]) + MULT16_32_Q15(interp[3],accum[3]); +    +      *out = PSHR32(sum,15); +      out += st->out_stride; +      out_sample++; +      last_sample += st->int_advance; +      samp_frac_num += st->frac_advance; +      if (samp_frac_num >= st->den_rate) +      { +         samp_frac_num -= st->den_rate; +         last_sample++; +      } +   } +   st->last_sample[channel_index] = last_sample; +   st->samp_frac_num[channel_index] = samp_frac_num; +   return out_sample; +} + +#ifdef FIXED_POINT +#else +/* This is the same as the previous function, except with a double-precision accumulator */ +static int resampler_basic_interpolate_double(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len) +{ +   int N = st->filt_len; +   int out_sample = 0; +   spx_word16_t *mem; +   int last_sample = st->last_sample[channel_index]; +   spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index]; +   mem = st->mem + channel_index * st->mem_alloc_size; +   while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len)) +   { +      int j; +      spx_word32_t sum=0; +       +      /* We need to interpolate the sinc filter */ +      double accum[4] = {0.f,0.f, 0.f, 0.f}; +      float interp[4]; +      const spx_word16_t *ptr; +      float alpha = ((float)samp_frac_num)/st->den_rate; +      int offset = samp_frac_num*st->oversample/st->den_rate; +      float frac = alpha*st->oversample - offset; +         /* This code is written like this to make it easy to optimise with SIMD. +      For most DSPs, it would be best to split the loops in two because most DSPs  +      have only two accumulators */ +      for (j=0;last_sample-N+1+j < 0;j++) +      { +         double curr_mem = mem[last_sample+j]; +         accum[0] += MULT16_16(curr_mem,st->sinc_table[4+(j+1)*st->oversample-offset-2]); +         accum[1] += MULT16_16(curr_mem,st->sinc_table[4+(j+1)*st->oversample-offset-1]); +         accum[2] += MULT16_16(curr_mem,st->sinc_table[4+(j+1)*st->oversample-offset]); +         accum[3] += MULT16_16(curr_mem,st->sinc_table[4+(j+1)*st->oversample-offset+1]); +      } +      ptr = in+st->in_stride*(last_sample-N+1+j); +      /* Do the new part */ +      for (;j<N;j++) +      { +         double curr_in = *ptr; +         ptr += st->in_stride; +         accum[0] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-2]); +         accum[1] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-1]); +         accum[2] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset]); +         accum[3] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset+1]); +      } +      cubic_coef(frac, interp); +      sum = interp[0]*accum[0] + interp[1]*accum[1] + interp[2]*accum[2] + interp[3]*accum[3]; +    +      *out = PSHR32(sum,15); +      out += st->out_stride; +      out_sample++; +      last_sample += st->int_advance; +      samp_frac_num += st->frac_advance; +      if (samp_frac_num >= st->den_rate) +      { +         samp_frac_num -= st->den_rate; +         last_sample++; +      } +   } +   st->last_sample[channel_index] = last_sample; +   st->samp_frac_num[channel_index] = samp_frac_num; +   return out_sample; +} +#endif + +static void update_filter(SpeexResamplerState *st) +{ +   spx_uint32_t old_length; +    +   old_length = st->filt_len; +   st->oversample = quality_map[st->quality].oversample; +   st->filt_len = quality_map[st->quality].base_length; +    +   if (st->num_rate > st->den_rate) +   { +      /* down-sampling */ +      st->cutoff = quality_map[st->quality].downsample_bandwidth * st->den_rate / st->num_rate; +      /* FIXME: divide the numerator and denominator by a certain amount if they're too large */ +      st->filt_len = st->filt_len*st->num_rate / st->den_rate; +      /* Round down to make sure we have a multiple of 4 */ +      st->filt_len &= (~0x3); +      if (2*st->den_rate < st->num_rate) +         st->oversample >>= 1; +      if (4*st->den_rate < st->num_rate) +         st->oversample >>= 1; +      if (8*st->den_rate < st->num_rate) +         st->oversample >>= 1; +      if (16*st->den_rate < st->num_rate) +         st->oversample >>= 1; +      if (st->oversample < 1) +         st->oversample = 1; +   } else { +      /* up-sampling */ +      st->cutoff = quality_map[st->quality].upsample_bandwidth; +   } + +   /* Choose the resampling type that requires the least amount of memory */ +   if (st->den_rate <= st->oversample) +   { +      spx_uint32_t i; +      if (!st->sinc_table) +         st->sinc_table = (spx_word16_t *)speex_alloc(st->filt_len*st->den_rate*sizeof(spx_word16_t)); +      else if (st->sinc_table_length < st->filt_len*st->den_rate) +      { +         st->sinc_table = (spx_word16_t *)speex_realloc(st->sinc_table,st->filt_len*st->den_rate*sizeof(spx_word16_t)); +         st->sinc_table_length = st->filt_len*st->den_rate; +      } +      for (i=0;i<st->den_rate;i++) +      { +         spx_int32_t j; +         for (j=0;j<st->filt_len;j++) +         { +            st->sinc_table[i*st->filt_len+j] = sinc(st->cutoff,((j-(spx_int32_t)st->filt_len/2+1)-((float)i)/st->den_rate), st->filt_len, quality_map[st->quality].window_func); +         } +      } +#ifdef FIXED_POINT +      st->resampler_ptr = resampler_basic_direct_single; +#else +      if (st->quality>8) +         st->resampler_ptr = resampler_basic_direct_double; +      else +         st->resampler_ptr = resampler_basic_direct_single; +#endif +      /*fprintf (stderr, "resampler uses direct sinc table and normalised cutoff %f\n", cutoff);*/ +   } else { +      spx_int32_t i; +      if (!st->sinc_table) +         st->sinc_table = (spx_word16_t *)speex_alloc((st->filt_len*st->oversample+8)*sizeof(spx_word16_t)); +      else if (st->sinc_table_length < st->filt_len*st->oversample+8) +      { +         st->sinc_table = (spx_word16_t *)speex_realloc(st->sinc_table,(st->filt_len*st->oversample+8)*sizeof(spx_word16_t)); +         st->sinc_table_length = st->filt_len*st->oversample+8; +      } +      for (i=-4;i<(spx_int32_t)(st->oversample*st->filt_len+4);i++) +         st->sinc_table[i+4] = sinc(st->cutoff,(i/(float)st->oversample - st->filt_len/2), st->filt_len, quality_map[st->quality].window_func); +#ifdef FIXED_POINT +      st->resampler_ptr = resampler_basic_interpolate_single; +#else +      if (st->quality>8) +         st->resampler_ptr = resampler_basic_interpolate_double; +      else +         st->resampler_ptr = resampler_basic_interpolate_single; +#endif +      /*fprintf (stderr, "resampler uses interpolated sinc table and normalised cutoff %f\n", cutoff);*/ +   } +   st->int_advance = st->num_rate/st->den_rate; +   st->frac_advance = st->num_rate%st->den_rate; + +    +   /* Here's the place where we update the filter memory to take into account +      the change in filter length. It's probably the messiest part of the code +      due to handling of lots of corner cases. */ +   if (!st->mem) +   { +      spx_uint32_t i; +      st->mem = (spx_word16_t*)speex_alloc(st->nb_channels*(st->filt_len-1) * sizeof(spx_word16_t)); +      for (i=0;i<st->nb_channels*(st->filt_len-1);i++) +         st->mem[i] = 0; +      st->mem_alloc_size = st->filt_len-1; +      /*speex_warning("init filter");*/ +   } else if (!st->started) +   { +      spx_uint32_t i; +      st->mem = (spx_word16_t*)speex_realloc(st->mem, st->nb_channels*(st->filt_len-1) * sizeof(spx_word16_t)); +      for (i=0;i<st->nb_channels*(st->filt_len-1);i++) +         st->mem[i] = 0; +      st->mem_alloc_size = st->filt_len-1; +      /*speex_warning("reinit filter");*/ +   } else if (st->filt_len > old_length) +   { +      spx_int32_t i; +      /* Increase the filter length */ +      /*speex_warning("increase filter size");*/ +      int old_alloc_size = st->mem_alloc_size; +      if (st->filt_len-1 > st->mem_alloc_size) +      { +         st->mem = (spx_word16_t*)speex_realloc(st->mem, st->nb_channels*(st->filt_len-1) * sizeof(spx_word16_t)); +         st->mem_alloc_size = st->filt_len-1; +      } +      for (i=st->nb_channels-1;i>=0;i--) +      { +         spx_int32_t j; +         spx_uint32_t olen = old_length; +         /*if (st->magic_samples[i])*/ +         { +            /* Try and remove the magic samples as if nothing had happened */ +             +            /* FIXME: This is wrong but for now we need it to avoid going over the array bounds */ +            olen = old_length + 2*st->magic_samples[i]; +            for (j=old_length-2+st->magic_samples[i];j>=0;j--) +               st->mem[i*st->mem_alloc_size+j+st->magic_samples[i]] = st->mem[i*old_alloc_size+j]; +            for (j=0;j<st->magic_samples[i];j++) +               st->mem[i*st->mem_alloc_size+j] = 0; +            st->magic_samples[i] = 0; +         } +         if (st->filt_len > olen) +         { +            /* If the new filter length is still bigger than the "augmented" length */ +            /* Copy data going backward */ +            for (j=0;j<olen-1;j++) +               st->mem[i*st->mem_alloc_size+(st->filt_len-2-j)] = st->mem[i*st->mem_alloc_size+(olen-2-j)]; +            /* Then put zeros for lack of anything better */ +            for (;j<st->filt_len-1;j++) +               st->mem[i*st->mem_alloc_size+(st->filt_len-2-j)] = 0; +            /* Adjust last_sample */ +            st->last_sample[i] += (st->filt_len - olen)/2; +         } else { +            /* Put back some of the magic! */ +            st->magic_samples[i] = (olen - st->filt_len)/2; +            for (j=0;j<st->filt_len-1+st->magic_samples[i];j++) +               st->mem[i*st->mem_alloc_size+j] = st->mem[i*st->mem_alloc_size+j+st->magic_samples[i]]; +         } +      } +   } else if (st->filt_len < old_length) +   { +      spx_uint32_t i; +      /* Reduce filter length, this a bit tricky. We need to store some of the memory as "magic" +         samples so they can be used directly as input the next time(s) */ +      for (i=0;i<st->nb_channels;i++) +      { +         spx_uint32_t j; +         spx_uint32_t old_magic = st->magic_samples[i]; +         st->magic_samples[i] = (old_length - st->filt_len)/2; +         /* We must copy some of the memory that's no longer used */ +         /* Copy data going backward */ +         for (j=0;j<st->filt_len-1+st->magic_samples[i]+old_magic;j++) +            st->mem[i*st->mem_alloc_size+j] = st->mem[i*st->mem_alloc_size+j+st->magic_samples[i]]; +         st->magic_samples[i] += old_magic; +      } +   } + +} + +SpeexResamplerState *speex_resampler_init(spx_uint32_t nb_channels, spx_uint32_t in_rate, spx_uint32_t out_rate, int quality, int *err) +{ +   return speex_resampler_init_frac(nb_channels, in_rate, out_rate, in_rate, out_rate, quality, err); +} + +SpeexResamplerState *speex_resampler_init_frac(spx_uint32_t nb_channels, spx_uint32_t ratio_num, spx_uint32_t ratio_den, spx_uint32_t in_rate, spx_uint32_t out_rate, int quality, int *err) +{ +   spx_uint32_t i; +   SpeexResamplerState *st; +   if (quality > 10 || quality < 0) +   { +      if (err) +         *err = RESAMPLER_ERR_INVALID_ARG; +      return NULL; +   } +   st = (SpeexResamplerState *)speex_alloc(sizeof(SpeexResamplerState)); +   st->initialised = 0; +   st->started = 0; +   st->in_rate = 0; +   st->out_rate = 0; +   st->num_rate = 0; +   st->den_rate = 0; +   st->quality = -1; +   st->sinc_table_length = 0; +   st->mem_alloc_size = 0; +   st->filt_len = 0; +   st->mem = 0; +   st->resampler_ptr = 0; +          +   st->cutoff = 1.f; +   st->nb_channels = nb_channels; +   st->in_stride = 1; +   st->out_stride = 1; +    +   /* Per channel data */ +   st->last_sample = (spx_int32_t*)speex_alloc(nb_channels*sizeof(int)); +   st->magic_samples = (spx_uint32_t*)speex_alloc(nb_channels*sizeof(int)); +   st->samp_frac_num = (spx_uint32_t*)speex_alloc(nb_channels*sizeof(int)); +   for (i=0;i<nb_channels;i++) +   { +      st->last_sample[i] = 0; +      st->magic_samples[i] = 0; +      st->samp_frac_num[i] = 0; +   } + +   speex_resampler_set_quality(st, quality); +   speex_resampler_set_rate_frac(st, ratio_num, ratio_den, in_rate, out_rate); + +    +   update_filter(st); +    +   st->initialised = 1; +   if (err) +      *err = RESAMPLER_ERR_SUCCESS; + +   return st; +} + +void speex_resampler_destroy(SpeexResamplerState *st) +{ +   speex_free(st->mem); +   speex_free(st->sinc_table); +   speex_free(st->last_sample); +   speex_free(st->magic_samples); +   speex_free(st->samp_frac_num); +   speex_free(st); +} + + + +static int speex_resampler_process_native(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len) +{ +   int j=0; +   int N = st->filt_len; +   int out_sample = 0; +   spx_word16_t *mem; +   spx_uint32_t tmp_out_len = 0; +   mem = st->mem + channel_index * st->mem_alloc_size; +   st->started = 1; +    +   /* Handle the case where we have samples left from a reduction in filter length */ +   if (st->magic_samples[channel_index]) +   { +      int istride_save; +      spx_uint32_t tmp_in_len; +      spx_uint32_t tmp_magic; +       +      istride_save = st->in_stride; +      tmp_in_len = st->magic_samples[channel_index]; +      tmp_out_len = *out_len; +      /* magic_samples needs to be set to zero to avoid infinite recursion */ +      tmp_magic = st->magic_samples[channel_index]; +      st->magic_samples[channel_index] = 0; +      st->in_stride = 1; +      speex_resampler_process_native(st, channel_index, mem+N-1, &tmp_in_len, out, &tmp_out_len); +      st->in_stride = istride_save; +      /*speex_warning_int("extra samples:", tmp_out_len);*/ +      /* If we couldn't process all "magic" input samples, save the rest for next time */ +      if (tmp_in_len < tmp_magic) +      { +         spx_uint32_t i; +         st->magic_samples[channel_index] = tmp_magic-tmp_in_len; +         for (i=0;i<st->magic_samples[channel_index];i++) +            mem[N-1+i]=mem[N-1+i+tmp_in_len]; +      } +      out += tmp_out_len*st->out_stride; +      *out_len -= tmp_out_len; +   } +    +   /* Call the right resampler through the function ptr */ +   out_sample = st->resampler_ptr(st, channel_index, in, in_len, out, out_len); +    +   if (st->last_sample[channel_index] < (spx_int32_t)*in_len) +      *in_len = st->last_sample[channel_index]; +   *out_len = out_sample+tmp_out_len; +   st->last_sample[channel_index] -= *in_len; +    +   for (j=0;j<N-1-(spx_int32_t)*in_len;j++) +      mem[j] = mem[j+*in_len]; +   for (;j<N-1;j++) +      mem[j] = in[st->in_stride*(j+*in_len-N+1)]; +    +   return RESAMPLER_ERR_SUCCESS; +} + +#define FIXED_STACK_ALLOC 1024 + +#ifdef FIXED_POINT +int speex_resampler_process_float(SpeexResamplerState *st, spx_uint32_t channel_index, const float *in, spx_uint32_t *in_len, float *out, spx_uint32_t *out_len) +{ +   spx_uint32_t i; +   int istride_save, ostride_save; +#ifdef VAR_ARRAYS +   spx_word16_t x[*in_len]; +   spx_word16_t y[*out_len]; +   /*VARDECL(spx_word16_t *x); +   VARDECL(spx_word16_t *y); +   ALLOC(x, *in_len, spx_word16_t); +   ALLOC(y, *out_len, spx_word16_t);*/ +   istride_save = st->in_stride; +   ostride_save = st->out_stride; +   for (i=0;i<*in_len;i++) +      x[i] = WORD2INT(in[i*st->in_stride]); +   st->in_stride = st->out_stride = 1; +   speex_resampler_process_native(st, channel_index, x, in_len, y, out_len); +   st->in_stride = istride_save; +   st->out_stride = ostride_save; +   for (i=0;i<*out_len;i++) +      out[i*st->out_stride] = y[i]; +#else +   spx_word16_t x[FIXED_STACK_ALLOC]; +   spx_word16_t y[FIXED_STACK_ALLOC]; +   spx_uint32_t ilen=*in_len, olen=*out_len; +   istride_save = st->in_stride; +   ostride_save = st->out_stride; +   while (ilen && olen) +   { +      spx_uint32_t ichunk, ochunk; +      ichunk = ilen; +      ochunk = olen; +      if (ichunk>FIXED_STACK_ALLOC) +         ichunk=FIXED_STACK_ALLOC; +      if (ochunk>FIXED_STACK_ALLOC) +         ochunk=FIXED_STACK_ALLOC; +      for (i=0;i<ichunk;i++) +         x[i] = WORD2INT(in[i*st->in_stride]); +      st->in_stride = st->out_stride = 1; +      speex_resampler_process_native(st, channel_index, x, &ichunk, y, &ochunk); +      st->in_stride = istride_save; +      st->out_stride = ostride_save; +      for (i=0;i<ochunk;i++) +         out[i*st->out_stride] = y[i]; +      out += ochunk; +      in += ichunk; +      ilen -= ichunk; +      olen -= ochunk; +   } +   *in_len -= ilen; +   *out_len -= olen;    +#endif +   return RESAMPLER_ERR_SUCCESS; +} +int speex_resampler_process_int(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_int16_t *in, spx_uint32_t *in_len, spx_int16_t *out, spx_uint32_t *out_len) +{ +   return speex_resampler_process_native(st, channel_index, in, in_len, out, out_len); +} +#else +int speex_resampler_process_float(SpeexResamplerState *st, spx_uint32_t channel_index, const float *in, spx_uint32_t *in_len, float *out, spx_uint32_t *out_len) +{ +   return speex_resampler_process_native(st, channel_index, in, in_len, out, out_len); +} +int speex_resampler_process_int(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_int16_t *in, spx_uint32_t *in_len, spx_int16_t *out, spx_uint32_t *out_len) +{ +   spx_uint32_t i; +   int istride_save, ostride_save; +#ifdef VAR_ARRAYS +   spx_word16_t x[*in_len]; +   spx_word16_t y[*out_len]; +   /*VARDECL(spx_word16_t *x); +   VARDECL(spx_word16_t *y); +   ALLOC(x, *in_len, spx_word16_t); +   ALLOC(y, *out_len, spx_word16_t);*/ +   istride_save = st->in_stride; +   ostride_save = st->out_stride; +   for (i=0;i<*in_len;i++) +      x[i] = in[i*st->in_stride]; +   st->in_stride = st->out_stride = 1; +   speex_resampler_process_native(st, channel_index, x, in_len, y, out_len); +   st->in_stride = istride_save; +   st->out_stride = ostride_save; +   for (i=0;i<*out_len;i++) +      out[i*st->out_stride] = WORD2INT(y[i]); +#else +   spx_word16_t x[FIXED_STACK_ALLOC]; +   spx_word16_t y[FIXED_STACK_ALLOC]; +   spx_uint32_t ilen=*in_len, olen=*out_len; +   istride_save = st->in_stride; +   ostride_save = st->out_stride; +   while (ilen && olen) +   { +      spx_uint32_t ichunk, ochunk; +      ichunk = ilen; +      ochunk = olen; +      if (ichunk>FIXED_STACK_ALLOC) +         ichunk=FIXED_STACK_ALLOC; +      if (ochunk>FIXED_STACK_ALLOC) +         ochunk=FIXED_STACK_ALLOC; +      for (i=0;i<ichunk;i++) +         x[i] = in[i*st->in_stride]; +      st->in_stride = st->out_stride = 1; +      speex_resampler_process_native(st, channel_index, x, &ichunk, y, &ochunk); +      st->in_stride = istride_save; +      st->out_stride = ostride_save; +      for (i=0;i<ochunk;i++) +         out[i*st->out_stride] = WORD2INT(y[i]); +      out += ochunk; +      in += ichunk; +      ilen -= ichunk; +      olen -= ochunk; +   } +   *in_len -= ilen; +   *out_len -= olen;    +#endif +   return RESAMPLER_ERR_SUCCESS; +} +#endif + +int speex_resampler_process_interleaved_float(SpeexResamplerState *st, const float *in, spx_uint32_t *in_len, float *out, spx_uint32_t *out_len) +{ +   spx_uint32_t i; +   int istride_save, ostride_save; +   spx_uint32_t bak_len = *out_len; +   istride_save = st->in_stride; +   ostride_save = st->out_stride; +   st->in_stride = st->out_stride = st->nb_channels; +   for (i=0;i<st->nb_channels;i++) +   { +      *out_len = bak_len; +      speex_resampler_process_float(st, i, in+i, in_len, out+i, out_len); +   } +   st->in_stride = istride_save; +   st->out_stride = ostride_save; +   return RESAMPLER_ERR_SUCCESS; +} + +                +int speex_resampler_process_interleaved_int(SpeexResamplerState *st, const spx_int16_t *in, spx_uint32_t *in_len, spx_int16_t *out, spx_uint32_t *out_len) +{ +   spx_uint32_t i; +   int istride_save, ostride_save; +   spx_uint32_t bak_len = *out_len; +   istride_save = st->in_stride; +   ostride_save = st->out_stride; +   st->in_stride = st->out_stride = st->nb_channels; +   for (i=0;i<st->nb_channels;i++) +   { +      *out_len = bak_len; +      speex_resampler_process_int(st, i, in+i, in_len, out+i, out_len); +   } +   st->in_stride = istride_save; +   st->out_stride = ostride_save; +   return RESAMPLER_ERR_SUCCESS; +} + +int speex_resampler_set_rate(SpeexResamplerState *st, spx_uint32_t in_rate, spx_uint32_t out_rate) +{ +   return speex_resampler_set_rate_frac(st, in_rate, out_rate, in_rate, out_rate); +} + +void speex_resampler_get_rate(SpeexResamplerState *st, spx_uint32_t *in_rate, spx_uint32_t *out_rate) +{ +   *in_rate = st->in_rate; +   *out_rate = st->out_rate; +} + +int speex_resampler_set_rate_frac(SpeexResamplerState *st, spx_uint32_t ratio_num, spx_uint32_t ratio_den, spx_uint32_t in_rate, spx_uint32_t out_rate) +{ +   spx_uint32_t fact; +   spx_uint32_t old_den; +   spx_uint32_t i; +   if (st->in_rate == in_rate && st->out_rate == out_rate && st->num_rate == ratio_num && st->den_rate == ratio_den) +      return RESAMPLER_ERR_SUCCESS; +    +   old_den = st->den_rate; +   st->in_rate = in_rate; +   st->out_rate = out_rate; +   st->num_rate = ratio_num; +   st->den_rate = ratio_den; +   /* FIXME: This is terribly inefficient, but who cares (at least for now)? */ +   for (fact=2;fact<=IMIN(st->num_rate, st->den_rate);fact++) +   { +      while ((st->num_rate % fact == 0) && (st->den_rate % fact == 0)) +      { +         st->num_rate /= fact; +         st->den_rate /= fact; +      } +   } +       +   if (old_den > 0) +   { +      for (i=0;i<st->nb_channels;i++) +      { +         st->samp_frac_num[i]=st->samp_frac_num[i]*st->den_rate/old_den; +         /* Safety net */ +         if (st->samp_frac_num[i] >= st->den_rate) +            st->samp_frac_num[i] = st->den_rate-1; +      } +   } +    +   if (st->initialised) +      update_filter(st); +   return RESAMPLER_ERR_SUCCESS; +} + +void speex_resampler_get_ratio(SpeexResamplerState *st, spx_uint32_t *ratio_num, spx_uint32_t *ratio_den) +{ +   *ratio_num = st->num_rate; +   *ratio_den = st->den_rate; +} + +int speex_resampler_set_quality(SpeexResamplerState *st, int quality) +{ +   if (quality > 10 || quality < 0) +      return RESAMPLER_ERR_INVALID_ARG; +   if (st->quality == quality) +      return RESAMPLER_ERR_SUCCESS; +   st->quality = quality; +   if (st->initialised) +      update_filter(st); +   return RESAMPLER_ERR_SUCCESS; +} + +void speex_resampler_get_quality(SpeexResamplerState *st, int *quality) +{ +   *quality = st->quality; +} + +void speex_resampler_set_input_stride(SpeexResamplerState *st, spx_uint32_t stride) +{ +   st->in_stride = stride; +} + +void speex_resampler_get_input_stride(SpeexResamplerState *st, spx_uint32_t *stride) +{ +   *stride = st->in_stride; +} + +void speex_resampler_set_output_stride(SpeexResamplerState *st, spx_uint32_t stride) +{ +   st->out_stride = stride; +} + +void speex_resampler_get_output_stride(SpeexResamplerState *st, spx_uint32_t *stride) +{ +   *stride = st->out_stride; +} + +int speex_resampler_skip_zeros(SpeexResamplerState *st) +{ +   spx_uint32_t i; +   for (i=0;i<st->nb_channels;i++) +      st->last_sample[i] = st->filt_len/2; +   return RESAMPLER_ERR_SUCCESS; +} + +int speex_resampler_reset_mem(SpeexResamplerState *st) +{ +   spx_uint32_t i; +   for (i=0;i<st->nb_channels*(st->filt_len-1);i++) +      st->mem[i] = 0; +   return RESAMPLER_ERR_SUCCESS; +} + +const char *speex_resampler_strerror(int err) +{ +   switch (err) +   { +      case RESAMPLER_ERR_SUCCESS: +         return "Success."; +      case RESAMPLER_ERR_ALLOC_FAILED: +         return "Memory allocation failed."; +      case RESAMPLER_ERR_BAD_STATE: +         return "Bad resampler state."; +      case RESAMPLER_ERR_INVALID_ARG: +         return "Invalid argument."; +      case RESAMPLER_ERR_PTR_OVERLAP: +         return "Input and output buffers overlap."; +      default: +         return "Unknown error. Bad error code or strange version mismatch."; +   } +} diff --git a/src/speex/speex_resampler.h b/src/speex/speex_resampler.h new file mode 100644 index 0000000..c44fbcd --- /dev/null +++ b/src/speex/speex_resampler.h @@ -0,0 +1,328 @@ +/* Copyright (C) 2007 Jean-Marc Valin +       +   File: speex_resampler.h +   Resampling code +       +   The design goals of this code are: +      - Very fast algorithm +      - Low memory requirement +      - Good *perceptual* quality (and not best SNR) + +   Redistribution and use in source and binary forms, with or without +   modification, are permitted provided that the following conditions are +   met: + +   1. Redistributions of source code must retain the above copyright notice, +   this list of conditions and the following disclaimer. + +   2. Redistributions in binary form must reproduce the above copyright +   notice, this list of conditions and the following disclaimer in the +   documentation and/or other materials provided with the distribution. + +   3. The name of the author may not be used to endorse or promote products +   derived from this software without specific prior written permission. + +   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +   IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +   DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +   POSSIBILITY OF SUCH DAMAGE. +*/ + + +#ifndef SPEEX_RESAMPLER_H +#define SPEEX_RESAMPLER_H + +#ifdef OUTSIDE_SPEEX + +/********* WARNING: MENTAL SANITY ENDS HERE *************/ + +/* If the resampler is defined outside of Speex, we change the symbol names so that  +   there won't be any clash if linking with Speex later on. */ + +/* #define RANDOM_PREFIX your software name here */ +#ifndef RANDOM_PREFIX +#error "Please define RANDOM_PREFIX (above) to something specific to your project to prevent symbol name clashes" +#endif + +#define CAT_PREFIX2(a,b) a ## b +#define CAT_PREFIX(a,b) CAT_PREFIX2(a, b) +       +#define speex_resampler_init CAT_PREFIX(RANDOM_PREFIX,_resampler_init) +#define speex_resampler_init_frac CAT_PREFIX(RANDOM_PREFIX,_resampler_init_frac) +#define speex_resampler_destroy CAT_PREFIX(RANDOM_PREFIX,_resampler_destroy) +#define speex_resampler_process_float CAT_PREFIX(RANDOM_PREFIX,_resampler_process_float) +#define speex_resampler_process_int CAT_PREFIX(RANDOM_PREFIX,_resampler_process_int) +#define speex_resampler_process_interleaved_float CAT_PREFIX(RANDOM_PREFIX,_resampler_process_interleaved_float) +#define speex_resampler_process_interleaved_int CAT_PREFIX(RANDOM_PREFIX,_resampler_process_interleaved_int) +#define speex_resampler_set_rate CAT_PREFIX(RANDOM_PREFIX,_resampler_set_rate) +#define speex_resampler_get_rate CAT_PREFIX(RANDOM_PREFIX,_resampler_get_rate) +#define speex_resampler_set_rate_frac CAT_PREFIX(RANDOM_PREFIX,_resampler_set_rate_frac) +#define speex_resampler_get_ratio CAT_PREFIX(RANDOM_PREFIX,_resampler_get_ratio) +#define speex_resampler_set_quality CAT_PREFIX(RANDOM_PREFIX,_resampler_set_quality) +#define speex_resampler_get_quality CAT_PREFIX(RANDOM_PREFIX,_resampler_get_quality) +#define speex_resampler_set_input_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_set_input_stride) +#define speex_resampler_get_input_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_get_input_stride) +#define speex_resampler_set_output_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_set_output_stride) +#define speex_resampler_get_output_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_get_output_stride) +#define speex_resampler_skip_zeros CAT_PREFIX(RANDOM_PREFIX,_resampler_skip_zeros) +#define speex_resampler_reset_mem CAT_PREFIX(RANDOM_PREFIX,_resampler_reset_mem) +#define speex_resampler_strerror CAT_PREFIX(RANDOM_PREFIX,_resampler_strerror) + +#define spx_int16_t short +#define spx_int32_t int +#define spx_uint16_t unsigned short +#define spx_uint32_t unsigned int +       +#else /* OUTSIDE_SPEEX */ + +#include "speex/speex_types.h" + +#endif /* OUTSIDE_SPEEX */ + +#ifdef __cplusplus +extern "C" { +#endif + +#define SPEEX_RESAMPLER_QUALITY_MAX 10 +#define SPEEX_RESAMPLER_QUALITY_MIN 0 +#define SPEEX_RESAMPLER_QUALITY_DEFAULT 4 +#define SPEEX_RESAMPLER_QUALITY_VOIP 3 +#define SPEEX_RESAMPLER_QUALITY_DESKTOP 5 + +enum { +   RESAMPLER_ERR_SUCCESS         = 0, +   RESAMPLER_ERR_ALLOC_FAILED    = 1, +   RESAMPLER_ERR_BAD_STATE       = 2, +   RESAMPLER_ERR_INVALID_ARG     = 3, +   RESAMPLER_ERR_PTR_OVERLAP     = 4, +    +   RESAMPLER_ERR_MAX_ERROR +}; + +struct SpeexResamplerState_; +typedef struct SpeexResamplerState_ SpeexResamplerState; + +/** Create a new resampler with integer input and output rates. + * @param nb_channels Number of channels to be processed + * @param in_rate Input sampling rate (integer number of Hz). + * @param out_rate Output sampling rate (integer number of Hz). + * @param quality Resampling quality between 0 and 10, where 0 has poor quality + * and 10 has very high quality. + * @return Newly created resampler state + * @retval NULL Error: not enough memory + */ +SpeexResamplerState *speex_resampler_init(spx_uint32_t nb_channels,  +                                          spx_uint32_t in_rate,  +                                          spx_uint32_t out_rate,  +                                          int quality, +                                          int *err); + +/** Create a new resampler with fractional input/output rates. The sampling  + * rate ratio is an arbitrary rational number with both the numerator and  + * denominator being 32-bit integers. + * @param nb_channels Number of channels to be processed + * @param ratio_num Numerator of the sampling rate ratio + * @param ratio_den Denominator of the sampling rate ratio + * @param in_rate Input sampling rate rounded to the nearest integer (in Hz). + * @param out_rate Output sampling rate rounded to the nearest integer (in Hz). + * @param quality Resampling quality between 0 and 10, where 0 has poor quality + * and 10 has very high quality. + * @return Newly created resampler state + * @retval NULL Error: not enough memory + */ +SpeexResamplerState *speex_resampler_init_frac(spx_uint32_t nb_channels,  +                                               spx_uint32_t ratio_num,  +                                               spx_uint32_t ratio_den,  +                                               spx_uint32_t in_rate,  +                                               spx_uint32_t out_rate,  +                                               int quality, +                                               int *err); + +/** Destroy a resampler state. + * @param st Resampler state + */ +void speex_resampler_destroy(SpeexResamplerState *st); + +/** Resample a float array. The input and output buffers must *not* overlap. + * @param st Resampler state + * @param channel_index Index of the channel to process for the multi-channel  + * base (0 otherwise) + * @param in Input buffer + * @param in_len Number of input samples in the input buffer. Returns the  + * number of samples processed + * @param out Output buffer + * @param out_len Size of the output buffer. Returns the number of samples written + */ +int speex_resampler_process_float(SpeexResamplerState *st,  +                                   spx_uint32_t channel_index,  +                                   const float *in,  +                                   spx_uint32_t *in_len,  +                                   float *out,  +                                   spx_uint32_t *out_len); + +/** Resample an int array. The input and output buffers must *not* overlap. + * @param st Resampler state + * @param channel_index Index of the channel to process for the multi-channel  + * base (0 otherwise) + * @param in Input buffer + * @param in_len Number of input samples in the input buffer. Returns the number + * of samples processed + * @param out Output buffer + * @param out_len Size of the output buffer. Returns the number of samples written + */ +int speex_resampler_process_int(SpeexResamplerState *st,  +                                 spx_uint32_t channel_index,  +                                 const spx_int16_t *in,  +                                 spx_uint32_t *in_len,  +                                 spx_int16_t *out,  +                                 spx_uint32_t *out_len); + +/** Resample an interleaved float array. The input and output buffers must *not* overlap. + * @param st Resampler state + * @param in Input buffer + * @param in_len Number of input samples in the input buffer. Returns the number + * of samples processed. This is all per-channel. + * @param out Output buffer + * @param out_len Size of the output buffer. Returns the number of samples written. + * This is all per-channel. + */ +int speex_resampler_process_interleaved_float(SpeexResamplerState *st,  +                                               const float *in,  +                                               spx_uint32_t *in_len,  +                                               float *out,  +                                               spx_uint32_t *out_len); + +/** Resample an interleaved int array. The input and output buffers must *not* overlap. + * @param st Resampler state + * @param in Input buffer + * @param in_len Number of input samples in the input buffer. Returns the number + * of samples processed. This is all per-channel. + * @param out Output buffer + * @param out_len Size of the output buffer. Returns the number of samples written. + * This is all per-channel. + */ +int speex_resampler_process_interleaved_int(SpeexResamplerState *st,  +                                             const spx_int16_t *in,  +                                             spx_uint32_t *in_len,  +                                             spx_int16_t *out,  +                                             spx_uint32_t *out_len); + +/** Set (change) the input/output sampling rates (integer value). + * @param st Resampler state + * @param in_rate Input sampling rate (integer number of Hz). + * @param out_rate Output sampling rate (integer number of Hz). + */ +int speex_resampler_set_rate(SpeexResamplerState *st,  +                              spx_uint32_t in_rate,  +                              spx_uint32_t out_rate); + +/** Get the current input/output sampling rates (integer value). + * @param st Resampler state + * @param in_rate Input sampling rate (integer number of Hz) copied. + * @param out_rate Output sampling rate (integer number of Hz) copied. + */ +void speex_resampler_get_rate(SpeexResamplerState *st,  +                              spx_uint32_t *in_rate,  +                              spx_uint32_t *out_rate); + +/** Set (change) the input/output sampling rates and resampling ratio  + * (fractional values in Hz supported). + * @param st Resampler state + * @param ratio_num Numerator of the sampling rate ratio + * @param ratio_den Denominator of the sampling rate ratio + * @param in_rate Input sampling rate rounded to the nearest integer (in Hz). + * @param out_rate Output sampling rate rounded to the nearest integer (in Hz). + */ +int speex_resampler_set_rate_frac(SpeexResamplerState *st,  +                                   spx_uint32_t ratio_num,  +                                   spx_uint32_t ratio_den,  +                                   spx_uint32_t in_rate,  +                                   spx_uint32_t out_rate); + +/** Get the current resampling ratio. This will be reduced to the least + * common denominator. + * @param st Resampler state + * @param ratio_num Numerator of the sampling rate ratio copied + * @param ratio_den Denominator of the sampling rate ratio copied + */ +void speex_resampler_get_ratio(SpeexResamplerState *st,  +                               spx_uint32_t *ratio_num,  +                               spx_uint32_t *ratio_den); + +/** Set (change) the conversion quality. + * @param st Resampler state + * @param quality Resampling quality between 0 and 10, where 0 has poor  + * quality and 10 has very high quality. + */ +int speex_resampler_set_quality(SpeexResamplerState *st,  +                                 int quality); + +/** Get the conversion quality. + * @param st Resampler state + * @param quality Resampling quality between 0 and 10, where 0 has poor  + * quality and 10 has very high quality. + */ +void speex_resampler_get_quality(SpeexResamplerState *st,  +                                 int *quality); + +/** Set (change) the input stride. + * @param st Resampler state + * @param stride Input stride + */ +void speex_resampler_set_input_stride(SpeexResamplerState *st,  +                                      spx_uint32_t stride); + +/** Get the input stride. + * @param st Resampler state + * @param stride Input stride copied + */ +void speex_resampler_get_input_stride(SpeexResamplerState *st,  +                                      spx_uint32_t *stride); + +/** Set (change) the output stride. + * @param st Resampler state + * @param stride Output stride + */ +void speex_resampler_set_output_stride(SpeexResamplerState *st,  +                                      spx_uint32_t stride); + +/** Get the output stride. + * @param st Resampler state copied + * @param stride Output stride + */ +void speex_resampler_get_output_stride(SpeexResamplerState *st,  +                                      spx_uint32_t *stride); + +/** Make sure that the first samples to go out of the resamplers don't have  + * leading zeros. This is only useful before starting to use a newly created  + * resampler. It is recommended to use that when resampling an audio file, as + * it will generate a file with the same length. For real-time processing, + * it is probably easier not to use this call (so that the output duration + * is the same for the first frame). + * @param st Resampler state + */ +int speex_resampler_skip_zeros(SpeexResamplerState *st); + +/** Reset a resampler so a new (unrelated) stream can be processed. + * @param st Resampler state + */ +int speex_resampler_reset_mem(SpeexResamplerState *st); + +/** Returns the English meaning for an error code + * @param err Error code + * @return English string + */ +const char *speex_resampler_strerror(int err); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/sydney.h b/src/sydney.h new file mode 100644 index 0000000..8733260 --- /dev/null +++ b/src/sydney.h @@ -0,0 +1,375 @@ +#ifndef foosydneyhfoo +#define foosydneyhfoo + +/* Requirements: + +- In sync mode, the device will automatically write data so that an initial read causes writes +of zeros to be issued to that one can do "while (1); {read(); write()} + +- All functions are thread-safe and can be called in any thread context. None of the functions is +async-signal safe. +   +- It is assumed that duplex streams have a single clock (synchronised) +*/ + +#include <sys/types.h> +#include <sys/param.h> +#include <inttypes.h> + +/* Detect byte order, based on sys/param.h */ +#if (defined(__BYTE_ORDER) && (__BYTE_ORDER == __LITTLE_ENDIAN)) || defined(WIN32) +#    define SA_LITTLE_ENDIAN 1 +#    undef SA_BIG_ENDIAN +#elif (defined(__BYTE_ORDER) && (__BYTE_ORDER == __BIG_ENDIAN)) +#    undef SA_LITTLE_ENDIAN +#    define SA_BIG_ENDIAN 1 +#else +#    error "Cannot determine byte order!" +#endif + +typedef struct sa_stream sa_stream_t; + +/** Volume that corresponds to muted in/out */ +#define SA_VOLUME_MUTED ((int32_t) (-0x80000000)) + +/** Ways to express seek offsets for pread/pwrite */ +typedef enum { +    SA_SEEK_RELATIVE, +    SA_SEEK_ABSOLUTE, +    SA_SEEK_RELATIVE_END, +    _SA_SEEK_MAX +} sa_seek_t; + +/** Supported formats */ +typedef enum { +    SA_PCM_FORMAT_U8, +    SA_PCM_FORMAT_ULAW, +    SA_PCM_FORMAT_ALAW, +    SA_PCM_FORMAT_S16_LE, +    SA_PCM_FORMAT_S16_BE, +    SA_PCM_FORMAT_S24_LE, +    SA_PCM_FORMAT_S24_BE, +    SA_PCM_FORMAT_S32_LE, +    SA_PCM_FORMAT_S32_BE, +    SA_PCM_FORMAT_FLOAT32_LE, +    SA_PCM_FORMAT_FLOAT32_BE, +    _SA_PCM_FORMAT_MAX +} sa_pcm_format_t; + +/* Native/reverse endianness definitions for PCM */ +#ifdef SA_LITTLE_ENDIAN +#define SA_PCM_FORMAT_S16_NE SA_PCM_FORMAT_S16_LE +#define SA_PCM_FORMAT_S24_NE SA_PCM_FORMAT_S24_LE +#define SA_PCM_FORMAT_S32_NE SA_PCM_FORMAT_S32_LE +#define SA_PCM_FORMAT_FLOAT32_NE SA_PCM_FORMAT_FLOAT32_LE +#define SA_PCM_FORMAT_S16_RE SA_PCM_FORMAT_S16_BE +#define SA_PCM_FORMAT_S24_RE SA_PCM_FORMAT_S24_BE +#define SA_PCM_FORMAT_S32_RE SA_PCM_FORMAT_S32_BE +#define SA_PCM_FORMAT_FLOAT32_RE SA_PCM_FORMAT_FLOAT32_BE +#else +#define SA_PCM_FORMAT_S16_NE SA_PCM_FORMAT_S16_BE +#define SA_PCM_FORMAT_S24_NE SA_PCM_FORMAT_S24_BE +#define SA_PCM_FORMAT_S32_NE SA_PCM_FORMAT_S32_BE +#define SA_PCM_FORMAT_FLOAT32_NE SA_PCM_FORMAT_FLOAT32_BE +#define SA_PCM_FORMAT_S16_RE SA_PCM_FORMAT_S16_LE +#define SA_PCM_FORMAT_S24_RE SA_PCM_FORMAT_S24_LE +#define SA_PCM_FORMAT_S32_RE SA_PCM_FORMAT_S32_LE +#define SA_PCM_FORMAT_FLOAT32_RE SA_PCM_FORMAT_FLOAT32_LE +#endif + +#define SA_CODEC_MPEG "mpeg" +#define SA_CODEC_AC3 "ac3" +#define SA_CODEC_GSM "gsm" +#define SA_CODEC_VORBIS "vorbis" +#define SA_CODEC_SPEEX "speex" + +/** Device opening modes */ +typedef enum { +    SA_MODE_WRONLY = 1, +    SA_MODE_RDONLY = 2, +    SA_MODE_RDWR   = 3, +    _SA_MODE_MAX   = 4, +} sa_mode_t; + +/** Error codes */ +typedef enum { +    SA_SUCCESS = 0, +    SA_ERROR_NOT_SUPPORTED = -1, +    SA_ERROR_INVALID = -2, +    SA_ERROR_STATE = -3, +    SA_ERROR_OOM = -4, +    SA_ERROR_NO_DEVICE = -5, +    SA_ERROR_NO_DRIVER = -6, +    SA_ERROR_NO_CODEC = -7, +    SA_ERROR_NO_PCM_FORMAT = -7, +    SA_ERROR_SYSTEM = -8, +    SA_ERROR_NO_INIT = -9, +    SA_ERROR_NO_META = -10, +    SA_ERROR_NO_DATA = -11, +    SA_ERROR_NO_SPACE = -12, +    _SA_ERROR_MAX = -13 +} sa_error_t; + +/** Possible events for notifications */ +typedef enum { +    SA_NOTIFY_REQUEST_START, +    SA_NOTIFY_REQUEST_STOP, +    SA_NOTIFY_CHANGED_READ_VOLUME, +    SA_NOTIFY_CHANGED_WRITE_VOLUME, +    SA_NOTIFY_CHANGED_DEVICE, +    _SA_NOTIFY_MAX +} sa_notify_t; + +/** Classes of events */ +typedef enum { +    SA_EVENT_REQUEST_IO, +    SA_EVENT_INIT_THREAD, +    SA_EVENT_NOTIFY, +    SA_EVENT_ERROR, +    _SA_EVENT_MAX +} sa_event_t; + +/** List of sample position queries */ +typedef enum { +    SA_POSITION_WRITE_DELAY, +    SA_POSITION_WRITE_HARDWARE, +    SA_POSITION_WRITE_SOFTWARE, +    SA_POSITION_READ_DELAY, +    SA_POSITION_READ_HARDWARE, +    SA_POSITION_READ_SOFTWARE, +    SA_POSITION_DUPLEX_DELAY, +    _SA_POSITION_MAX +} sa_position_t; + +/* Channel positions */ +typedef enum { +    SA_CHANNEL_MONO, +    SA_CHANNEL_LEFT, +    SA_CHANNEL_RIGHT, +    SA_CHANNEL_CENTER, +    SA_CHANNEL_FRONT_LEFT, +    SA_CHANNEL_FRONT_RIGHT, +    SA_CHANNEL_FRONT_CENTER, +    SA_CHANNEL_REAR_LEFT, +    SA_CHANNEL_REAR_RIGHT, +    SA_CHANNEL_REAR_CENTER, +    SA_CHANNEL_LFE, +    SA_CHANNEL_FRONT_LEFT_OF_CENTER, +    SA_CHANNEL_FRONT_RIGHT_OF_CENTER, +    SA_CHANNEL_SIDE_LEFT, +    SA_CHANNEL_SIDE_RIGHT, +    SA_CHANNEL_TOP_CENTER, +    SA_CHANNEL_TOP_FRONT_LEFT, +    SA_CHANNEL_TOP_FRONT_RIGHT, +    SA_CHANNEL_TOP_FRONT_CENTER, +    SA_CHANNEL_TOP_REAR_LEFT, +    SA_CHANNEL_TOP_REAR_RIGHT, +    SA_CHANNEL_TOP_REAR_CENTER, +    SA_CHANNEL_AUX0, +    SA_CHANNEL_AUX1, +    SA_CHANNEL_AUX2, +    SA_CHANNEL_AUX3, +    SA_CHANNEL_AUX4, +    SA_CHANNEL_AUX5, +    SA_CHANNEL_AUX6, +    SA_CHANNEL_AUX7, +    SA_CHANNEL_AUX8, +    SA_CHANNEL_AUX9, +    SA_CHANNEL_AUX10, +    SA_CHANNEL_AUX11, +    SA_CHANNEL_AUX12, +    SA_CHANNEL_AUX13, +    SA_CHANNEL_AUX14, +    SA_CHANNEL_AUX15, +    SA_CHANNEL_AUX16, +    SA_CHANNEL_AUX17, +    SA_CHANNEL_AUX18, +    SA_CHANNEL_AUX19, +    SA_CHANNEL_AUX20, +    SA_CHANNEL_AUX21, +    SA_CHANNEL_AUX22, +    SA_CHANNEL_AUX23, +    SA_CHANNEL_AUX24, +    SA_CHANNEL_AUX25, +    SA_CHANNEL_AUX26, +    SA_CHANNEL_AUX27, +    SA_CHANNEL_AUX28, +    SA_CHANNEL_AUX29, +    SA_CHANNEL_AUX30, +    SA_CHANNEL_AUX31, +    _SA_CHANNEL_MAX +} sa_channel_t; + +typedef enum { +    SA_STATE_INIT, +    SA_STATE_RUNNING, +    SA_STATE_STOPPED, +    /* put more stuff */ +    _SA_STATE_MAX, +} sa_state_t; + +typedef enum { +    SA_XRUN_MODE_STOP, +    SA_XRUN_MODE_SPIN, +    _SA_XRUN_MODE_MAX +} sa_xrun_mode_t; + +typedef enum { +    SA_ADJUST_UP = 1, +    SA_ADJUST_DOWN = -1, +    SA_ADJUST_NONE = 0, +} sa_adjust_t; + +/* Some kind of meta information.  */ +#define SA_META_CLIENT_NAME "sydney.client-name"     /* utf-8 */  +#define SA_META_PROCESS_ID "sydney.process-id"       /* getpid() */ +#define SA_META_LANGUAGE "sydney.language"           /* de_DE and similar */ + +/* Some kind of meta information. Not filled in */ +#define SA_META_STREAM_NAME "sydney.stream-name"     /* utf-8 */  +#define SA_META_ICON_NAME "sydney.icon-name"         /* file name (no slashes) */ +#define SA_META_ICON_PNG "sydney.icon-png"           /* PNG blob */ +#define SA_META_ROLE "sydney.role"                   /* one of: "music", "phone", "game", "event" */ +#define SA_META_X11_DISPLAY "sydney.x11-display"     /* X11 display */ +#define SA_META_X11_WINDOW "sydney.x11-window"       /* X11 window id */ + +/** Main callback function */ +typedef int (*sa_event_callback_t)(sa_stream_t *s, sa_event_t event); + +/** Create an opaque (e.g. AC3) codec stream */ +int sa_stream_create_opaque(sa_stream_t **s, const char *client_name, sa_mode_t mode, const char *codec); + +/** Normal way to open a PCM device */ +int sa_stream_create_pcm(sa_stream_t **s, const char *client_name, sa_mode_t mode, sa_pcm_format_t format, unsigned rate, unsigned nchannels); + +/** Initialise the device */ +int sa_stream_open(sa_stream_t *s); + +/** Close/destroy everything */ +int sa_stream_destroy(sa_stream_t *s); + +/* "Soft" params */ +int sa_stream_set_write_lower_watermark(sa_stream_t *s, size_t size); +int sa_stream_set_read_lower_watermark(sa_stream_t *s, size_t size); +int sa_stream_set_write_user_size(sa_stream_t *s, size_t size); +int sa_stream_set_read_user_size(sa_stream_t *s, size_t size); + +/** Set the mapping between channels and the loudspeakers */ +int sa_stream_set_channel_map(sa_stream_t *s, const sa_channel_t map[], unsigned n); + +/** Whether xruns cause the card to reset */ +int sa_stream_set_xrun_mode(sa_stream_t *s, sa_xrun_mode_t mode); + +/** Set the device to non-interleaved mode */ +int sa_stream_set_non_interleaved(sa_stream_t *s, int enable); + +/** Select driver */ +int sa_stream_set_driver(sa_stream_t *s, const char *driver); + +/** Start callback */ +int sa_stream_start_thread(sa_stream_t *s, sa_event_callback_t callback); + +/** Start callback */ +int sa_stream_stop_thread(sa_stream_t *s); + +/** Change the device connected to the stream */ +int sa_stream_change_device(sa_stream_t *s, const char *device_name); + +/** volume in hundreths of dB*/ +int sa_stream_change_read_volume(sa_stream_t *s, const int32_t vol[], unsigned n); + +/** volume in hundreths of dB*/ +int sa_stream_change_write_volume(sa_stream_t *s, const int32_t vol[], unsigned n); + +/** Change the sampling rate */ +int sa_stream_change_rate(sa_stream_t *s, unsigned rate); + +/** Change some meta data that is attached to the stream */ +int sa_stream_change_meta_data(sa_stream_t *s, const char *name, const void *data, size_t size); + +/** Associate opaque user data */ +int sa_stream_change_user_data(sa_stream_t *s, const void *value); + +/* Hardware-related. This is implementation-specific and hardware specific. */ +int sa_stream_set_adjust_rate(sa_stream_t *s, sa_adjust_t direction); +int sa_stream_set_adjust_nchannels(sa_stream_t *s, sa_adjust_t direction); +int sa_stream_set_adjust_pcm_format(sa_stream_t *s, sa_adjust_t direction); +int sa_stream_set_adjust_watermarks(sa_stream_t *s, sa_adjust_t direction); + +/* Query functions */ + +int sa_stream_get_mode(sa_stream_t *s, sa_mode_t *access_mode); +int sa_stream_get_codec(sa_stream_t *s, char *codec, size_t *size); +int sa_stream_get_pcm_format(sa_stream_t *s, sa_pcm_format_t *format); +int sa_stream_get_rate(sa_stream_t *s, unsigned *rate); +int sa_stream_get_nchannels(sa_stream_t *s, int *nchannels); +int sa_stream_get_user_data(sa_stream_t *s, void **value); +int sa_stream_get_write_lower_watermark(sa_stream_t *s, size_t *size); +int sa_stream_get_read_lower_watermark(sa_stream_t *s, size_t *size); +int sa_stream_get_write_upper_watermark(sa_stream_t *s, size_t *size); +int sa_stream_get_read_upper_watermark(sa_stream_t *s, size_t *size); +int sa_stream_get_channel_map(sa_stream_t *s, sa_channel_t map[], unsigned *n); +int sa_stream_get_xrun_mode(sa_stream_t *s, sa_xrun_mode_t *mode); +int sa_stream_get_non_interleaved(sa_stream_t *s, int *enabled); +int sa_stream_get_dynamic_rate(sa_stream_t *s, int *enabled); +int sa_stream_get_driver(sa_stream_t *s, char *driver_name, size_t *size); +int sa_stream_get_device(sa_stream_t *s, char *device_name, size_t *size); +int sa_stream_get_read_volume(sa_stream_t *s, int32_t vol[], unsigned *n); +int sa_stream_get_write_volume(sa_stream_t *s, int32_t vol[], unsigned *n); +int sa_stream_get_meta_data(sa_stream_t *s, const char *name, void*data, size_t *size); +int sa_stream_get_adjust_rate(sa_stream_t *s, sa_adjust_t *direction); +int sa_stream_get_adjust_nchannels(sa_stream_t *s, sa_adjust_t *direction); +int sa_stream_get_adjust_pcm_format(sa_stream_t *s, sa_adjust_t *direction); +int sa_stream_get_adjust_watermarks(sa_stream_t *s, sa_adjust_t *direction); + +/** Get current state of the audio device */ +int sa_stream_get_state(sa_stream_t *s, sa_state_t *state); + +/** Obtain the error code */ +int sa_stream_get_event_error(sa_stream_t *s, sa_error_t *error); + +/** Obtain the notification code */ +int sa_stream_get_event_notify(sa_stream_t *s, sa_notify_t *notify); + +/** sync/timing */ +int sa_stream_get_position(sa_stream_t *s, sa_position_t position, int64_t *pos); + + +/* Blocking IO calls */ + +/** Interleaved capture function */ +int sa_stream_read(sa_stream_t *s, void *data, size_t nbytes); +/** Non-interleaved capture function */ +int sa_stream_read_ni(sa_stream_t *s, unsigned channel, void *data, size_t nbytes); + +/** Interleaved playback function */ +int sa_stream_write(sa_stream_t *s, const void *data, size_t nbytes); +/** Non-interleaved playback function */ +int sa_stream_write_ni(sa_stream_t *s, unsigned channel, const void *data, size_t nbytes); +/** Interleaved playback function with seek offset */ +int sa_stream_pwrite(sa_stream_t *s, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence); +/** Non-interleaved playback function with seek offset */ +int sa_stream_pwrite_ni(sa_stream_t *s, unsigned channel, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence); + + +/** Query how much can be read without blocking */ +int sa_stream_get_read_size(sa_stream_t *s, size_t *size); +/** Query how much can be written without blocking */ +int sa_stream_get_write_size(sa_stream_t *s, size_t *size); + + +/* Control/xrun */ + +/** Resume playing after a pause */ +int sa_stream_resume(sa_stream_t *s); + +/** Pause audio playback (do not empty the buffer) */ +int sa_stream_pause(sa_stream_t *s); + +/** Block until all audio has been played */ +int sa_stream_drain(sa_stream_t *s); + +/** Return a human readable error */ +const char *sa_strerror(int code); + +#endif diff --git a/src/test-asyncq.c b/src/test-asyncq.c new file mode 100644 index 0000000..26dbc55 --- /dev/null +++ b/src/test-asyncq.c @@ -0,0 +1,62 @@ +#include <stdlib.h> + +#include "asyncq.h" +#include "thread.h" +#include "macro.h" + +#define ITERATIONS_MAX 1000 + +static void thread(void *userdata) { +    sa_asyncq_t *q = userdata; +    int i; +     +    for (i = 0; i < ITERATIONS_MAX; i++) { +        sa_asyncq_item_t *i; + +        i = sa_asyncq_get(q); +        sa_assert(i); + +        sa_asyncq_push(q, i); + +        if (rand() & 1) +            sa_thread_yield(); +    } +} + +int main(int argc, char *argv[]) { +    int j; +    sa_thread_t *t; +    sa_asyncq_t q; +    sa_asyncq_item_t *i; + +    sa_assert_success(sa_asyncq_init(&q)); +     +    t = sa_thread_new(thread, &q); +    sa_assert(t); + +    for (j = 0; j < ITERATIONS_MAX; j++) { +         +        do { +            i = sa_asyncq_pop(&q, 0); +            printf("%s ", i ? "gotcha" : "miss"); + +            if (i) +                sa_asyncq_recycle(&q, i); +        } while (i); + +        if (rand() & 1) +            sa_thread_yield(); +    } + +    printf("\n"); +     +    sa_thread_free(t); + +    while (sa_asyncq_pop(&q, 1)) +        ; + +    sa_asyncq_done(&q); +     + +    return 0; +} diff --git a/src/test-bufferq.c b/src/test-bufferq.c new file mode 100644 index 0000000..45d65eb --- /dev/null +++ b/src/test-bufferq.c @@ -0,0 +1,42 @@ +#include "bufferq.h" +#include "malloc.h" + +int main(int argc, char *argv[]) { + +    sa_bufferq_t q; + +    sa_bufferq_init(&q, 1, 1); + +    sa_bufferq_push(&q, 0, "{AAAAAAAA}", 10, 0, SA_SEEK_RELATIVE, SA_BUFFERQ_ITEM_STATIC); +    sa_bufferq_push(&q, 0, "<BBBBBBBB>", 10, 5, SA_SEEK_RELATIVE, SA_BUFFERQ_ITEM_STATIC); +    sa_bufferq_push(&q, 0, "[CCCC]", 6, -18, SA_SEEK_RELATIVE, SA_BUFFERQ_ITEM_STATIC); +    sa_bufferq_push(&q, 0, "(DDDD)", 6, -3, SA_SEEK_ABSOLUTE, SA_BUFFERQ_ITEM_STATIC); +    sa_bufferq_push(&q, 0, sa_strdup("XXX"), 3, 10, SA_SEEK_RELATIVE_END, SA_BUFFERQ_ITEM_DYNAMIC); +    sa_bufferq_push(&q, 0, "YYYYY", 5, -4, SA_SEEK_RELATIVE, SA_BUFFERQ_ITEM_CONCATENATED); + +    sa_bufferq_realloc(&q); + +    for (;;) { +        void *b[1]; +        size_t size; +         +        sa_bufferq_get(&q, b, &size); + +        if (size == 0) +            break; + +        printf("Got %u bytes: ", size); +        if (b[0]) +            fwrite(b[0], size, 1, stdout); +        else +            printf("empty"); + +        printf("\n"); + +        sa_bufferq_drop(&q, size); +    } +     +    sa_bufferq_done(&q); + +    return 0; +} diff --git a/src/test-llist.c b/src/test-llist.c new file mode 100644 index 0000000..2059ef8 --- /dev/null +++ b/src/test-llist.c @@ -0,0 +1,34 @@ +#include "llist.h" + +struct foobar { +    SA_LLIST_ITEM(struct foobar, list); +}; + + +static SA_LLIST_HEAD(struct foobar, list); + +int main(int argc, char *argv[]) { +    struct foobar a, b, c; + +    SA_LLIST_HEAD_INIT(struct foobar, list); +     +    SA_LLIST_ITEM_INIT(struct foobar, list, &a); +    SA_LLIST_ITEM_INIT(struct foobar, list, &b); +    SA_LLIST_ITEM_INIT(struct foobar, list, &c); + +    SA_LLIST_PREPEND(struct foobar, list, list, &a); +    SA_LLIST_INSERT_BEFORE(struct foobar, list, list, &a, &b); +    SA_LLIST_INSERT_AFTER(struct foobar, list, list, &a, &c); + +    sa_assert(list == &b); +    sa_assert(list->list_next == &a); +    sa_assert(list->list_next->list_next == &c); + +    SA_LLIST_REMOVE(struct foobar, list, list, &a); +    SA_LLIST_REMOVE(struct foobar, list, list, &b); +    SA_LLIST_REMOVE(struct foobar, list, list, &c); + +    sa_assert(!list); +     +    return 0; +} diff --git a/src/test-pull.c b/src/test-pull.c new file mode 100644 index 0000000..7f93906 --- /dev/null +++ b/src/test-pull.c @@ -0,0 +1,73 @@ +#include <errno.h> +#include <stdio.h> +#include <assert.h> +#include <string.h> +#include <unistd.h> + +#include "sydney.h" +#include "macro.h" + +#define ASSERT_SUCCESS(x) do { \ +    int _r; \ +    if ((_r = x)) { \ +        fprintf(stderr, "Operation <%s> failed: %s%s%s\n", \ +                #x, \ +                sa_strerror(_r), \ +                _r == SA_ERROR_SYSTEM ? "; " : "", _r == SA_ERROR_SYSTEM ? strerror(errno) : ""); \ +    } \ +    assert(_r == SA_SUCCESS); \ +} while(0) + +#define FREQ 440 + +static const float data[4] = { 0.0, 1.0, 0.0, -1.0 }; + +static int callback(sa_stream_t *s, sa_event_t e) { +    switch (e) { +        case SA_EVENT_INIT_THREAD: +            printf("Thread initialized.\n"); +            return 0; + +        case SA_EVENT_ERROR: { +            int e; +            ASSERT_SUCCESS(sa_stream_get_event_error(s, &e)); +            printf("Error: %s\n", sa_strerror(e)); +            return -1; +        } + +        case SA_EVENT_NOTIFY: +            printf("Notified.\n"); +            return 0; + +        case SA_EVENT_REQUEST_IO: + +            ASSERT_SUCCESS(sa_stream_write(s, data, sizeof(data))); +            return 0; + +        case _SA_EVENT_MAX: +            ; +    } + +    sa_assert_not_reached(); +} + +int main(int argc, char *argv[]) { + +    sa_stream_t *s; + +    ASSERT_SUCCESS(sa_stream_create_pcm(&s, "Sine Test (pull)", SA_MODE_WRONLY, SA_PCM_FORMAT_FLOAT32_NE, FREQ * 4, 1)); +    ASSERT_SUCCESS(sa_stream_change_device(s, "/dev/dsp1")); +    ASSERT_SUCCESS(sa_stream_open(s)); + +    ASSERT_SUCCESS(sa_stream_start_thread(s, callback)); + +    sleep(20); +     +    ASSERT_SUCCESS(sa_stream_stop_thread(s)); + +    ASSERT_SUCCESS(sa_stream_drain(s)); + +    ASSERT_SUCCESS(sa_stream_destroy(s)); +     +    return 0; +} diff --git a/src/test-sine.c b/src/test-sine.c new file mode 100644 index 0000000..07f3868 --- /dev/null +++ b/src/test-sine.c @@ -0,0 +1,51 @@ +#include <errno.h> +#include <stdio.h> +#include <assert.h> +#include <string.h> + +#include "sydney.h" + +#define ASSERT_SUCCESS(x) do { \ +    int _r; \ +    if ((_r = x)) { \ +        fprintf(stderr, "Operation <%s> failed: %s%s%s\n", \ +                #x, \ +                sa_strerror(_r), \ +                _r == SA_ERROR_SYSTEM ? "; " : "", _r == SA_ERROR_SYSTEM ? strerror(errno) : ""); \ +    } \ +    assert(_r == SA_SUCCESS); \ +} while(0) + +#define FREQ 440 + +int main(int argc, char *argv[]) { + +    sa_stream_t *s; +    float data[4] = { 0.0, 1.0, 0.0, -1.0 }; +    int i, j; + +    ASSERT_SUCCESS(sa_stream_create_pcm(&s, "Sine Test", SA_MODE_WRONLY, SA_PCM_FORMAT_FLOAT32_NE, FREQ * 4, 1)); +    ASSERT_SUCCESS(sa_stream_change_device(s, "/dev/dsp1")); +    ASSERT_SUCCESS(sa_stream_set_dynamic_rate(s, 1)); +    sa_stream_change_meta_data(s, SA_META_CLIENT_NAME, argv[0], strlen(argv[0])); +    ASSERT_SUCCESS(sa_stream_open(s)); + +    for (j = 0; j < 10; j++) { +        int v; + +        v = -j*500; +         +/*         ASSERT_SUCCESS(sa_stream_change_rate(dev, FREQ*4+100*j)); */ +        ASSERT_SUCCESS(sa_stream_change_write_volume(s, &v, 1)); +                 +        for (i = 0; i < FREQ; i++) +            ASSERT_SUCCESS(sa_stream_write(s, data, sizeof(data))); +    } + +         +    ASSERT_SUCCESS(sa_stream_drain(s)); + +    ASSERT_SUCCESS(sa_stream_destroy(s)); +     +    return 0; +} diff --git a/src/thread.c b/src/thread.c new file mode 100644 index 0000000..26deccb --- /dev/null +++ b/src/thread.c @@ -0,0 +1,214 @@ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <pthread.h> +#include <sched.h> +#include <errno.h> + +#include "thread.h" +#include "malloc.h" +#include "once.h" +#include "macro.h" + +struct sa_thread { +    pthread_t id; +    sa_thread_func_t thread_func; +    void *userdata; +    int running; +    pthread_mutex_t running_mutex; +}; + +struct sa_tls { +    pthread_key_t key; +}; + +static sa_tls_t *thread_tls; +static sa_once_t thread_tls_once = SA_ONCE_INIT; + +static void tls_free_cb(void *p) { +    sa_thread_t *t = p; + +    sa_assert(t); +     +    if (!t->thread_func)  +        /* This is a foreign thread, we need to free the struct */ +        sa_free(t); +} + +static void thread_tls_once_func(void) { +    thread_tls = sa_tls_new(tls_free_cb); +} + +static void* internal_thread_func(void *userdata) { +    sa_thread_t *t = userdata; +    sa_assert(t); + +    t->id = pthread_self(); +    sa_tls_set(thread_tls, t); + +    t->thread_func(t->userdata); + +    sa_assert_success(pthread_mutex_lock(&t->running_mutex)); +    t->running = 0; +    sa_assert_success(pthread_mutex_unlock(&t->running_mutex)); +     +    return NULL; +} + +sa_thread_t* sa_thread_new(sa_thread_func_t thread_func, void *userdata) { +    sa_thread_t *t; + +    sa_assert(thread_func); +     +    if (sa_once(&thread_tls_once, thread_tls_once_func) < 0 || !thread_tls) +        return NULL; + +    if (!(t = sa_new(sa_thread_t, 1))) +        return NULL; +     +    t->thread_func = thread_func; +    t->userdata = userdata; + +    sa_assert_success(pthread_mutex_init(&t->running_mutex, NULL)); +    t->running = 1; +     +    if (pthread_create(&t->id, NULL, internal_thread_func, t) < 0) { +        sa_assert_success(pthread_mutex_destroy(&t->running_mutex)); +        sa_free(t); +        return NULL; +    } + +    return t; +} + +int sa_thread_is_running(sa_thread_t *t) { +    int b; +    sa_assert(t); + +    if (!t->thread_func) { +        /* Mhmm, this is a foreign thread, t->running is not +         * necessarily valid. We misuse pthread_getschedparam() to +         * check if the thread is valid. This might not be portable. */ + +        int policy; +        struct sched_param param; +         +        return pthread_getschedparam(t->id, &policy, ¶m) >= 0 || errno != ESRCH; +    } + +    sa_assert_success(pthread_mutex_lock(&t->running_mutex)); +    b = t->running; +    sa_assert_success(pthread_mutex_unlock(&t->running_mutex)); +     +    return !!b; +} + +void sa_thread_free(sa_thread_t *t) { +    sa_assert(t); +     +    sa_thread_join(t); +    sa_assert_success(pthread_mutex_destroy(&t->running_mutex)); +    sa_free(t); +} + +int sa_thread_join(sa_thread_t *t) { +    sa_assert(t); +     +    return pthread_join(t->id, NULL); +} + +sa_thread_t* sa_thread_self(void) { +    sa_thread_t *t; +     +    if (sa_once(&thread_tls_once, thread_tls_once_func) < 0 || !thread_tls) +        return NULL; + +    if ((t = sa_tls_get(thread_tls))) +        return t; + +    /* This is a foreign thread, let's create a pthread structure to +     * make sure that we can always return a sensible pointer */ +     +    if (!(t = sa_new(sa_thread_t, 1))) +        return NULL; +     +    t->id = pthread_self(); +    t->thread_func = NULL; +    t->userdata = NULL; +    t->running = 1; + +    sa_tls_set(thread_tls, t); +     +    return t; +} + +int sa_thread_is_self(sa_thread_t *t) { +    sa_thread_t *c; +    sa_assert(t); + +    if (sa_once(&thread_tls_once, thread_tls_once_func) < 0 || !thread_tls) +        return 0; + +    if ((c = sa_tls_get(thread_tls))) +        return c == t; + +    return 0; +} + + +void* sa_thread_get_data(sa_thread_t *t) { +    sa_assert(t); + +    return t->userdata; +} + +void sa_thread_set_data(sa_thread_t *t, void *userdata) { +    sa_assert(t); + +    t->userdata = userdata; +} + +void sa_thread_yield(void) { +#ifdef HAVE_PTHREAD_YIELD +    pthread_yield(); +#else +    sa_assert_success(sched_yield()); +#endif +} + +sa_tls_t* sa_tls_new(sa_free_func_t free_cb) { +    sa_tls_t *t; + +    if (!(t = sa_new(sa_tls_t, 1))) +        return NULL; + +    if (pthread_key_create(&t->key, free_cb) < 0) { +        sa_free(t); +        return NULL; +    } +         +    return t; +} + +void sa_tls_free(sa_tls_t *t) { +    sa_assert(t); + +    sa_assert_success(pthread_key_delete(t->key)); +    sa_free(t); +} + +void *sa_tls_get(sa_tls_t *t) { +    sa_assert(t); +     +    return pthread_getspecific(t->key); +} + +void *sa_tls_set(sa_tls_t *t, void *userdata) { +    void *r; +     +    r = pthread_getspecific(t->key); +    sa_assert_success(pthread_setspecific(t->key, userdata)); +    return r; +} + diff --git a/src/thread.h b/src/thread.h new file mode 100644 index 0000000..ddd2604 --- /dev/null +++ b/src/thread.h @@ -0,0 +1,28 @@ +#ifndef foosydneythreadhfoo +#define foosydneythreadhfoo + +typedef struct sa_thread sa_thread_t; + +typedef void (*sa_thread_func_t) (void *userdata); + +sa_thread_t* sa_thread_new(sa_thread_func_t sa_thread_func, void *userdata); +void sa_thread_free(sa_thread_t *t); +int sa_thread_join(sa_thread_t *t); +int sa_thread_is_running(sa_thread_t *t); +sa_thread_t *sa_thread_self(void); +void sa_thread_yield(void); +int sa_thread_is_self(sa_thread_t *t); + +void* sa_thread_get_data(sa_thread_t *t); +void sa_thread_set_data(sa_thread_t *t, void *userdata); + +typedef struct sa_tls sa_tls_t; + +typedef void (*sa_free_func_t) (void *data); + +sa_tls_t* sa_tls_new(sa_free_func_t f); +void sa_tls_free(sa_tls_t *t); +void * sa_tls_get(sa_tls_t *t); +void *sa_tls_set(sa_tls_t *t, void *userdata); + +#endif diff --git a/src/volscale.c b/src/volscale.c new file mode 100644 index 0000000..2075b90 --- /dev/null +++ b/src/volscale.c @@ -0,0 +1,67 @@ +#include <liboil/liboil.h> + +#include "macro.h" +#include "volscale.h" + +static void volscale_u8(void *_dst, size_t dstr, const void *_src, size_t sstr, int32_t factor, int32_t divisor, size_t bytes) { +    uint8_t *dst = _dst; +    const uint8_t *src = _src; +     +    for (; bytes > 0; bytes --) { +        int32_t t = (((int32_t) *src - 0x80) * factor) / divisor; +        *dst = t < -0x80 ? 0 : (t > 0x7F ? 0xFF : (int8_t) (t+0x80)); +         +        src += sstr; +        dst += dstr; +    } +} + +static void volscale_s16(void *_dst, size_t dstr, const void *_src, size_t sstr, int32_t factor, int32_t divisor, size_t bytes) { +    int16_t *dst = _dst; +    const int16_t *src = _src; +    unsigned n = bytes / sizeof(int16_t); +     +    for (; n > 0; n--) { +        int32_t t = ((int32_t) *src * factor) / divisor; +        *dst = t < -0x8000 ? 0x8000 : (t > 0x7FFF ? 0x7FFF : (int16_t) t); +         +        src += sstr / sizeof(int16_t); +        dst += dstr / sizeof(int16_t); +    } +} + +static void volscale_s32(void *_dst, size_t dstr, const void *_src, size_t sstr, int32_t factor, int32_t divisor, size_t bytes) { +    int32_t *dst = _dst; +    const int32_t *src = _src; +    unsigned n = bytes / sizeof(int32_t); +     +    for (; n > 0; n--) { +        int64_t t = ((int64_t) *src * factor) / divisor; +        *dst = t < -0x80000000L ? (int32_t) 0x80000000L : (t > 0x7fffffffL ? (int32_t) 0x7fffffffL : (int32_t) t); +         +        src += sstr / sizeof(int32_t); +        dst += dstr / sizeof(int32_t); +    } +} + +static void volscale_f32(void *_dst, size_t dstr, const void *_src, size_t sstr, int32_t factor, int32_t divisor, size_t size) { +    float *dst = _dst; +    const float *src = _src; +    float f = (float) factor / (float) divisor; +     +    oil_scalarmult_f32(dst, dstr, src, sstr, &f, size / sizeof(float)); +} + +sa_volscale_func_t sa_get_volscale_func(sa_pcm_format_t f) { +     +    static const sa_volscale_func_t funcs[_SA_PCM_FORMAT_MAX] = { +        [SA_PCM_FORMAT_U8] = volscale_u8, +        [SA_PCM_FORMAT_S16_NE] = volscale_s16, +        [SA_PCM_FORMAT_S32_NE] = volscale_s32, +        [SA_PCM_FORMAT_FLOAT32_NE] = volscale_f32 +    }; + +    sa_assert(f < _SA_PCM_FORMAT_MAX); + +    return funcs[f]; +} diff --git a/src/volscale.h b/src/volscale.h new file mode 100644 index 0000000..fe6e037 --- /dev/null +++ b/src/volscale.h @@ -0,0 +1,13 @@ +#ifndef foosydneyvolscalehfoo +#define foosydneyvolscalehfoo + +#include <sys/types.h> +#include <inttypes.h> + +#include "sydney.h" + +typedef void (*sa_volscale_func_t) (void *dst, size_t dstr, const void *src, size_t sstr, int32_t factor, int32_t divisor, size_t bytes); + +sa_volscale_func_t sa_get_volscale_func(sa_pcm_format_t f); + +#endif diff --git a/src/zero.c b/src/zero.c new file mode 100644 index 0000000..4f477dc --- /dev/null +++ b/src/zero.c @@ -0,0 +1,53 @@ +#include <string.h> + +#include "macro.h" +#include "zero.h" + +static void zero_u8(void *dst, size_t dstr, size_t bytes) { +    uint8_t *d = dst; + +    if (dstr == 1) +        memset(dst, 0x80, bytes); +    else { +        for (; bytes > 0; bytes --, d += dstr) +            *d = 0x80; +    }        +} + +static void zero_16(void *dst, size_t dstr, size_t bytes) { +    uint16_t *d = dst; +    unsigned n = bytes/sizeof(uint16_t); + +    if (dstr == sizeof(uint16_t)) +        memset(dst, 0, bytes); +    else { +        for (; n > 0; n --, d += dstr/sizeof(uint16_t)) +            *d = 0; +    }        +} + +static void zero_32(void *dst, size_t dstr, size_t bytes) { +    uint32_t *d = dst; +    unsigned n = bytes/sizeof(float); + +    if (dstr == sizeof(uint32_t)) +        memset(dst, 0, bytes); +    else { +        for (; n > 0; n --, d += dstr/sizeof(uint32_t)) +            *d = 0; +    }        +} + +sa_zero_func_t sa_get_zero_func(sa_pcm_format_t f) { + +    static const sa_zero_func_t funcs[_SA_PCM_FORMAT_MAX] = { +        [SA_PCM_FORMAT_U8] = zero_u8, +        [SA_PCM_FORMAT_S16_NE] = zero_16, +        [SA_PCM_FORMAT_S32_NE] = zero_32, +        [SA_PCM_FORMAT_FLOAT32_NE] = zero_32 +    }; + +    sa_assert(f < _SA_PCM_FORMAT_MAX); + +    return funcs[f]; +} diff --git a/src/zero.h b/src/zero.h new file mode 100644 index 0000000..6f59bdb --- /dev/null +++ b/src/zero.h @@ -0,0 +1,13 @@ +#ifndef foosydneyzerohfoo +#define foosydneyzerohfoo + +#include <sys/types.h> +#include <inttypes.h> + +#include "sydney.h" + +typedef void (*sa_zero_func_t) (void *dst, size_t dstr, size_t bytes); + +sa_zero_func_t sa_get_zero_func(sa_pcm_format_t f); + +#endif | 
