Защо получавам различни стойности, когато чета байтове от NSData в зависимост от това в какъв ред получавам байтовете?

Добре, това е по-скоро „Какво, по дяволите, става?“ отколкото истински проблем. Но като се има предвид моята относителна неопитност с 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. Страхотно. По принцип, ако редът, в който се дават стойностите на променливите, не съответства на реда, в който са дефинирани, това обърква нещата. Диапазоните не изглежда да оказват никакво влияние върху това поведение.

Някой има ли представа какво става тук?


person Septih    schedule 22.02.2010    source източник
comment
Трябва да предоставите своя код, който дефинира променливите на диапазона, тъй като проблемът най-вероятно е там.   -  person Alex Brown    schedule 22.02.2010
comment
Добавих ги. Първоначално мислех за това, но тъй като можех да ги променя без ефект, не ми се стори полезно.   -  person Septih    schedule 22.02.2010


Отговори (1)


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;

което означава, че вторият член е дължина, а не крайното местоположение. Със сигурност не искате да прочетете 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};

и опитайте отново.

person kennytm    schedule 22.02.2010
comment
Прав си! И така, какво по дяволите става? проблемът е само, че по някакъв начин получавах правилните отговори, въпреки че кодът беше ужасно грешен :) Благодаря ви много. - person Septih; 22.02.2010