summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2007-10-01 20:16:28 +0000
committerLennart Poettering <lennart@poettering.net>2007-10-01 20:16:28 +0000
commit7d83e5c7816b5e343695a75ba58b32dbe1be969a (patch)
treebfd1dfc9b7c8f4a2aaf66c1b30e78355dee8c88a /src
parent762196328ab7e60f1d2908fd5a337d2ca99726dd (diff)
move all sources down to a seperate src/ tree
git-svn-id: file:///home/lennart/svn/public/libsydney/trunk@34 9ba3c220-e4d3-45a2-8aa3-73fcc9aff6ce
Diffstat (limited to 'src')
-rw-r--r--src/Makefile47
-rw-r--r--src/TODO29
-rw-r--r--src/add.c51
-rw-r--r--src/add.h13
-rw-r--r--src/asyncq.c102
-rw-r--r--src/asyncq.h49
-rw-r--r--src/bbuffer.c77
-rw-r--r--src/bbuffer.h19
-rw-r--r--src/bufferq.c270
-rw-r--r--src/bufferq.h42
-rw-r--r--src/byteswap.c57
-rw-r--r--src/byteswap.h12
-rw-r--r--src/common.c1266
-rw-r--r--src/common.h67
-rw-r--r--src/continued-fraction.c69
-rw-r--r--src/continued-fraction.h6
-rw-r--r--src/converter.c743
-rw-r--r--src/converter.h82
-rw-r--r--src/driver.h34
-rw-r--r--src/format.c438
-rw-r--r--src/format.h13
-rw-r--r--src/g711.c2531
-rw-r--r--src/g711.h40
-rw-r--r--src/interleave.c64
-rw-r--r--src/interleave.h12
-rw-r--r--src/llist.h70
-rw-r--r--src/macro.h104
-rw-r--r--src/malloc.c13
-rw-r--r--src/malloc.h19
-rw-r--r--src/meta-name-table.gperf11
-rw-r--r--src/mutex.c97
-rw-r--r--src/mutex.h19
-rw-r--r--src/once.c58
-rw-r--r--src/once.h17
-rw-r--r--src/oss.c858
-rw-r--r--src/resample.c42
-rw-r--r--src/resample.h14
-rw-r--r--src/speex/arch.h197
-rw-r--r--src/speex/resample.c1114
-rw-r--r--src/speex/speex_resampler.h328
-rw-r--r--src/sydney.h375
-rw-r--r--src/test-asyncq.c62
-rw-r--r--src/test-bufferq.c42
-rw-r--r--src/test-llist.c34
-rw-r--r--src/test-pull.c73
-rw-r--r--src/test-sine.c51
-rw-r--r--src/thread.c214
-rw-r--r--src/thread.h28
-rw-r--r--src/volscale.c67
-rw-r--r--src/volscale.h13
-rw-r--r--src/zero.c53
-rw-r--r--src/zero.h13
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, &param) >= 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