- ベストアンサー
第7ビットが0の4バイト分計算
お世話になります。ID3v2の仕様で、タグ部分のサイズを表す数字が 「第7ビットがすべて0になるようにエンコードされた4バイトのデータ であり、第7ビットは無視するため全部で28ビット」 なので、例をあげると、 0x00000201 → 257(普通は513) となります。これをファイルから読み込む時、どのようにして読み込んだらいいでしょうか。 1バイトずつcharに入れて、128の重み(普通は256)を付けて計算したら良いかと思いましたが、試しに //cに1バイト読み込んだと仮定 char c = 0xAC; unsigned int i = 0; i += c; とすると、iが -84 になってしまいました。(172になって欲しかった) 聞きたいことは以下の2つです。 1.第7ビットを無視するデータを4バイト分読み込んで、整数にするにはどうしたらいいのか 2.もしくは、ファイルから1バイトずつ読み込んで整数にするにはどうすればいいのか です。何か分かり難い文章ですが、よろしくお願いしますm(__)m
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
#1 redfox63 さん,各バイトの MSB は無視すべきなので, 8ビットずつじゃなくて7ビットずつシフトしないとだめです. それと,ID3 のタグサイズフィールドはビッグエンディアンです. (手元の MP3 ファイルで確認済.) unsigned char buf[BUFSIZE]; unsigned size, i, j; // タグのサイズフィールドが fread() などを使って // buf[i ~ (i+3)] に 読み込まれているとすると, size = 0; for(j = 0; j < 4; j++) { size = (size << 7) | (buf[i + j] & 0x7F); } printf("サイズ:%u\n", size); // あるいは fgetc() を使う場合には, FILE *fp; int c; size = 0; for(i = 0; i < 4; i++) { if((c = fgetc(fp)) == EOF) goto FileReadError; size = (size << 7) | (c & 0x7F); } printf("サイズ:%u\n", size); ID3タグ (Wikipedia) http://ja.wikipedia.org/wiki/ID3%E3%82%BF%E3%82%B0
その他の回答 (2)
- redfox63
- ベストアンサー率71% (1325/1856)
なるほど … 調べもせずに回答するとこうなってしまうのです m(__)m noocyte お手数掛けました サイズの計算には 7ビットシフトですね ・・・
- redfox63
- ベストアンサー率71% (1325/1856)
charなので 符号付8ビット整数になります int(または unshigned int)に代入する際にコンパイラの仕様によって符号拡張される場合があるため -84になってします unsigned charなら符号なし8ビット整数なので 期待通り172になります unsigned int i = 0; unsigned char c = 0xAC; // 下位7ビットのみなら 0x7fでマスクする i += ( c & 0x7f ); ファイルから読むなら unshigned charのバッファに読み込み 4バイトづつintに整形でしょう unsigned char buf[256]; int nAns; fread( buf, sizeof( buf ), fp ); for ( int n=0; n< 256; n += 4 ) { nAns = buf[ n ] & 0x7f; nAns += ( buf[ n+1 ] & 0x7f ) << 8; nAns += ( buf[ n+2 ] & 0x7f ) << 16; nAns += ( buf[ n+3 ] & 0x7f ) << 24; } といった具合でしょう または unsigned int buf[64] fread( buf, sizeof( buf ), fp ); for ( n = 0; n < 64; n++ ) { buf[n] &= 0x7f7f7f7f; }
お礼
ありがとうございます(^o^)できました。