Разделить UInt32 (аудио кадр) на два SInt16 (левый и правый)? - PullRequest
0 голосов
/ 09 марта 2010

Полный нуб к чему-то более низкому уровню, чем Java, погружение в аудио iPhone и получение информации из всех типов доступа к указателям / необработанным данным.

Я работаю с некоторым примером кода , который читает WAV-файл с диска и возвращает стерео сэмплы в виде отдельных значений UInt32. Если я правильно понимаю, это просто удобный способ вернуть 32-битную память, необходимую для создания двух 16-битных выборок. В конце концов эти данные записываются в буфер, и аудиоустройство забирает их в будущем. Несмотря на то, что данные записываются в виде блоков размером с UInt32, в конечном итоге они интерпретируются как пары 16-битных выборок.

Мне нужна помощь в разбивке этих кадров UInt32 на левый и правый сэмплы. Я предполагаю, что захочу преобразовать каждый UInt32 в SInt16, поскольку аудиосэмпл является значением со знаком. Мне кажется, что для эффективности я должен иметь возможность просто указывать на одни и те же блоки в памяти и избегать любого копирования.

Итак, в псевдокоде это будет примерно так:

UInt32 myStereoFrame = getFramefromFilePlayer;

SInt16* leftChannel = getFirst16Bits(myStereoFrame);
SInt16* rightChannel = getSecond16Bits(myStereoFrame);

Может кто-нибудь помочь мне превратить мой псевдо-код в реальный код?

Edit:

Большое спасибо zneak за этот ответ, который прекрасно работает:

SInt16* left = (SInt16*)&myUInt32Chunk;
SInt16* right = left + 1;

Теперь, чтобы собрать мои SInt16s в UInt32 (при условии, что я не хочу просто использовать мою исходную переменную myStereoFrame), мне нужно будет сделать более или менее то же самое в обратном порядке: выстроить два моих SInt16 в ряд смежных слоты памяти, а затем приведите эту память к UInt32.

Итак, я делаю массив:

SInt16 newFrameInMemory[2] = {*left, *right}

А затем скопируйте всю длину этого массива в UInt32

UInt32 newFrame32 = newFrameInMemory

Хотя это не сработает, но если я сделаю это немного уродливым - приведу массив к указателю, а затем разыменую указатель, это сработает.

UInt32 newFrame32 = *((UInt32*)&newFrameInMemory)

Есть ли более красивый способ сделать это?

Ответы [ 2 ]

1 голос
/ 09 марта 2010

Это довольно просто:

SInt16* left = (SInt16*)&myUInt32Chunk;
SInt16* right = left + 1;

Если iPhone не имеет порядкового номера, в этом случае вам придется инвертировать right и left.

Поскольку int можно рассматривать как два смежных short s, вам просто нужно получить адрес для него, а затем сделать точно так, как если бы это были действительно два short s.

0 голосов
/ 19 сентября 2010

iPhone имеет младший порядковый номер: -)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...