summaryrefslogtreecommitdiffstats
path: root/audio/reorder_ch.c
diff options
context:
space:
mode:
Diffstat (limited to 'audio/reorder_ch.c')
-rw-r--r--audio/reorder_ch.c36
1 files changed, 35 insertions, 1 deletions
diff --git a/audio/reorder_ch.c b/audio/reorder_ch.c
index 4b51a79439..330a807eae 100644
--- a/audio/reorder_ch.c
+++ b/audio/reorder_ch.c
@@ -1368,7 +1368,6 @@ void reorder_channel_nch(void *buf,
samples, samplesize);
}
-
#ifdef TEST
static void test_copy(int channels) {
@@ -1398,3 +1397,38 @@ int main(int argc, char *argv[]) {
}
#endif
+
+static inline void reorder_to_planar_(void *restrict out, const void *restrict in,
+ size_t size, size_t nchan, size_t nmemb) {
+ size_t i, c;
+ char *outptr = (char *) out;
+ size_t instep = nchan * size;
+
+ for (c = 0; c < nchan; ++c) {
+ const char *inptr = ((const char *) in) + c * size;
+ for (i = 0; i < nmemb; ++i, inptr += instep, outptr += size) {
+ memcpy(outptr, inptr, size);
+ }
+ }
+}
+
+void reorder_to_planar(void *restrict out, const void *restrict in,
+ size_t size, size_t nchan, size_t nmemb)
+{
+ // special case for mono (nothing to do...)
+ if (nchan == 1)
+ memcpy(out, in, size * nchan * nmemb);
+ // these calls exist to insert an inline copy of to_planar_ here with known
+ // value of size to help the compiler replace the memcpy calls by mov
+ // instructions
+ else if (size == 1)
+ reorder_to_planar_(out, in, 1, nchan, nmemb);
+ else if (size == 2)
+ reorder_to_planar_(out, in, 2, nchan, nmemb);
+ else if (size == 4)
+ reorder_to_planar_(out, in, 4, nchan, nmemb);
+ // general case (calls memcpy a lot, should actually never happen, but
+ // stays here for correctness purposes)
+ else
+ reorder_to_planar_(out, in, size, nchan, nmemb);
+}