Почему я получаю разные значения при чтении байтов из NSData в зависимости от того, в каком порядке я получаю байты? - PullRequest
3 голосов
/ 22 февраля 2010

Хорошо, это больше «Что, черт возьми, происходит?» чем актуальная проблема. Но, учитывая мою относительную неопытность с C, это может привести к большим проблемам.

По сути, я анализирую заголовок файла wav и извлекаю значения. В моем заголовочном файле определены переменные класса:

short channels;
int sampleRate;
int bytesPerSecond;
short bytesPerSample;
short bitsPerSample;
unsigned int size;  

И функция в классе для получения этих значений:

NSData * fileData = [[NSData alloc] initWithContentsOfFile:filePath];
[fileData getBytes:&channels range:CHANNELS_R];
[fileData getBytes:&sampleRate range:SAMPLES_R];
[fileData getBytes:&bytesPerSecond range:BYTES_PER_SEC_R];
[fileData getBytes:&bytesPerSample range:BYTES_PER_SAMPLE_R];
[fileData getBytes:&bitsPerSample range:BITS_PER_SAMPLE_R];
[fileData getBytes:&size range:LENGTH_R];

Диапазоны определены ранее:

const NSRange CHANNELS_R = {22,23};
const NSRange SAMPLES_R = {24,27};
const NSRange BYTES_PER_SEC_R = {28,31};
const NSRange BYTES_PER_SAMPLE_R = {32,33};
const NSRange BITS_PER_SAMPLE_R = {34,35};
const NSRange LENGTH_R = {40,43};

Это работает нормально, и я получаю все значения, но, если я переместу одну из строк вверх в порядке или одно из определений переменных в заголовке, они получат совершенно другое значение. например у тестового wav, над которым я работаю, частота дискретизации 8000. С помощью приведенного выше кода я получаю правильное значение. Но если я переместу строку, которая присваивает ей значение выше линии для каналов, я получу 524288000. Отлично. По сути, если порядок, в котором переменным присваивается их значение, не соответствует порядку, в котором они определены, он портит его. Диапазоны, похоже, не влияют на это поведение.

Кто-нибудь знает, что здесь происходит?

1 Ответ

6 голосов
/ 22 февраля 2010
const NSRange CHANNELS_R = {22,23};
const NSRange SAMPLES_R = {24,27};
const NSRange BYTES_PER_SEC_R = {28,31};
const NSRange BYTES_PER_SAMPLE_R = {32,33};
const NSRange BITS_PER_SAMPLE_R = {34,35};
const NSRange LENGTH_R = {40,43};

Нет, NSRange так не работает.Определение NSRange:

typedef struct _NSRange {
   NSUInteger location;
   NSUInteger length;
} NSRange;

, что означает, что 2-й элемент - это длина, а не конечное местоположение.Конечно, вы не хотите читать 23 байта в short (который переполняет буфер и переопределяет другие переменные и вызывает явление, которое вы получаете).Измените их на

const NSRange CHANNELS_R = {22,2};
const NSRange SAMPLES_R = {24,4};
const NSRange BYTES_PER_SEC_R = {28,4};
const NSRange BYTES_PER_SAMPLE_R = {32,2};
const NSRange BITS_PER_SAMPLE_R = {34,2};
const NSRange LENGTH_R = {40,4};

и попробуйте снова.

...