summaryrefslogtreecommitdiffstats
path: root/src/byteswap.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/byteswap.c')
-rw-r--r--src/byteswap.c57
1 files changed, 57 insertions, 0 deletions
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];
+}
+