Handmade Hero»Forums»Code
Daniel Rasmussen
6 posts
Easy audio un-interleaving
Edited by Daniel Rasmussen on
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;
        }
    }
Mārtiņš Možeiko
2559 posts / 2 projects
Easy audio un-interleaving
Edited by Mārtiņš Možeiko 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.
10 posts
Easy audio un-interleaving
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
Daniel Rasmussen
6 posts
Easy audio un-interleaving
Edited by Daniel Rasmussen on
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.