Easy audio un-interleaving

Figured out a way to un-interleave the sound-data in place with one pass, with a simple algorithm. The principle is the see where a byte is supposed to go, save the value at the location, write into location, Repeat from where you are at now.

I was a little surprised that this concept wasn't brought up on the stream.

(Horrible C/pseudo code by someone who has never written any C, also untested)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
uint32 PointAt = 1;
int32 GetValueNext = SampleData[PointAt];
    for(uint32 SampleIndex = 1;
        SampleIndex < Result.SampleCount - 1;
        ++SampleIndex)
    {
        int32 GetValue = GetValueNext;
        uint32 WasPoint = PointAt;
        PointAt = RoundUpStub(PointAt/2); // Round up, also a stub

        if(IsOddThisReallyIsAStub(WasPoint)) // Check if value is an odd number
        {
            PointAt = PointAt+Result.SampleCount/2-1;
            GetValueNext = SampleData[PointAt];
            SampleData[PointAt] = GetValue;
        }
        else
        {
            GetValueNext = SampleData[PointAt];
            SampleData[PointAt] = GetValue;
        }
    }

Edited by Daniel Rasmussen on
Doesn't work for me:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <stdint.h>
#include <stdio.h>

int main()
{
  int16_t SampleData[] = { 1, -1, 2, -2, 3, -3, 4, -4, 5, -5, 6, -6, 7, -7, 8, -8 };
  uint32_t SampleCount = 8;

  uint32_t PointAt = 1;
  int16_t GetValueNext = SampleData[PointAt];
  for (uint32_t SampleIndex = 1; SampleIndex < SampleCount - 1; ++SampleIndex)
  {
    int16_t GetValue = GetValueNext;
    uint32_t WasPoint = PointAt;
    PointAt = (PointAt+1)/2;

    if (WasPoint & 1)
    {
      PointAt = PointAt + SampleCount/2 - 1;
      GetValueNext = SampleData[PointAt];
      SampleData[PointAt] = GetValue;
    }
    else
    {
      GetValueNext = SampleData[PointAt];
      SampleData[PointAt] = GetValue;
    }
  }

  for (uint32_t i=0; i<SampleCount*2; i++)
  {
    printf("%i ", SampleData[i]);
  }
  printf("\n");
}


This prints out:
1
1 3 -1 -2 -1 -3 4 -4 5 -5 6 -6 7 -7 8 -8


But it should print out:
1
1 2 3 4 5 6 7 8 -1 -2 -3 -4 -5 -6 -7 -8


If I change SampleCount variable to 16 (I think you are counting sample for all channels together, not per channel), then it prints out:
1
1 5 -1 -2 2 -3 4 -4 3 -5 6 -6 7 -7 8 -8

which is also incorrect.

Edited by Mārtiņš Možeiko on
So you're probably trying to implement this:
https://en.wikipedia.org/wiki/In-...re_matrices:_Following_the_cycles

But your program will fail because there might be several cycles to follow. And finding such cycles is kind of a hard problem with no additional space. I wrote this kind of algorithm myself:
https://forums.handmadehero.org/i...p/forum?view=topic&catid=4&id=710
m1el
So you're probably trying to implement this:
en.wikipedia.org/wiki/In-place_matrix_tr...Following_the_cycles

But your program will fail because there might be several cycles to follow. And finding such cycles is kind of a hard problem with no additional space. I wrote this kind of algorithm myself:
forums.handmadehero.org/index.php/forum?...topic&catid=4&id=710

Yeah seemingly I did. Haven't put to much thought into how it would perform. Only that cache locality could be a problem.

Hopefully fixed it, I commented in the fix. Edit: Maybe not

Edit: Ok, after some more testing, my algorithm just plainly doesn't work the way I hoped.

Hmm... Power of 2 problem perhaps?, Maybe give the array some pad bytes to untangle it from going in loops over the same bits. I'll do some more testing tomorrow.

Edited by Daniel Rasmussen on