Why am I getting different values when reading bytes from NSData depending on what order I get the bytes in?
Ok, this is more of a 'What the hell is going on?' than an actual problem. But given my relative inexperience with C, it could alude to greater problems.
Basically, I'm parsing a wav file's header and grabbing out the values. In my header file I have the class variables defined:
short channels;
int sampleRate;
int bytesPerSecond;
short bytesPerSample;
short bitsPerSample;
unsigned int size;
And the function in the class for getting these values goes:
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];
The ranges are defined earlier:
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};
This works fine and I get all the values, but, if I move one of the lines up in the order, or one of the variable definitions in the header they get a completely different value. e.g. the test wav I'm working on has a sample rate of 8000. With the above code I get the correct value. But if I move the line that assigns it the value up above the line for the channels, I get 524288000. Great. Basically, if the order in which the variables are given their value doesn't correspond to the order in which they are defined, it messes it up. The ranges don't seem to have any impact on this behaviour.
Anyone have a clue as to what's going on here?
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};
No, NSRange
doesn't work like that. The definition of NSRange
is
typedef struct _NSRange {
NSUInteger location;
NSUInteger length;
} NSRange;
which means the 2nd member is a length, not the end location. Surely you don't want to read 23 bytes into a short
(which overflows the buffer and override other variables and causes the phenomenon you get). Change them to
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};
and try again.
精彩评论