24bitのオーディオデータを作ったり読みこもうとしてもObjective-C(というかC言語)では24bitの型がありませんので、符号付き32bit整数の上位24bit分を使うというのが簡単な方法ではないかと思います。
ただこの場合、32bitの下位8bitは単純に切り捨てられますので、音にこだわるのであればディザをかけたりしたほうが良いのかもしれませんが、とりあえず今回は無視します。
32bit領域のAlignedHighなデータとして渡したりするのであれば何もしなくてもいいですが、32bit領域でAlignedLowな24bitのデータにしなくちゃいけないなんて時があったりしたら、
SInt32 value;
という、あるオーディオのデータがあったとして、
value >>= 8;
としてやります。
処理系によって算術シフトになるか論理シフトが変わるらしいですが、Xcodeでgccを使っているのであればこの場合算術シフトで、valueがマイナスのときは上位8bitが1で埋め尽くされています。
ちなみに、IntelMac想定の検証コード。
#import <Foundation/Foundation.h> void logBit (SInt32 value) { printf("MSB "); for (NSInteger i = 3; i >= 0; i--) { Byte *valuePtr = (Byte *)&value; for (NSInteger j = 7; j >= 0; j--) { SInt32 isBitOn = (valuePtr[i] & (1 << j)) ? YES : NO; printf("%d", isBitOn); } printf(" "); } printf(" LSB\n\n"); } int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; SInt32 value = INT32_MIN; printf("value = %d\n", value); logBit(value); SInt32 sValue = value; sValue >>= 8; printf("signed shift value = %d\n", sValue); logBit(sValue); UInt32 uValue = (UInt32)value; uValue >>= 8; printf("unsigned shift value = %u\n", uValue); logBit(uValue); [pool drain]; return 0; }
実行すると…
value = -2147483648 MSB 10000000 00000000 00000000 00000000 LSB signed shift value = -8388608 MSB 11111111 10000000 00000000 00000000 LSB unsigned shift value = 8388608 MSB 00000000 10000000 00000000 00000000 LSB
という感じになります。