🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

3回答

1977閲覧

大きいサイズの.wavファイルサイズが正常に取得出来ない。

退会済みユーザー

退会済みユーザー

総合スコア0

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2021/01/16 09:54

編集2021/01/17 01:34

提示コードの下部の音データサイズのコメント部のコードですが45mbの音楽データを読み込ませると222と表示されるのはなぜでしょうか?
短いファイルでは問題なくファイルサイズが8000などと表示されるのですがどうしたらいいのでしょうか?

イメージ説明
イメージ説明

** printf("# 音データのサイズ: %lld\n", chunk.DataSize); ** コード部です。

cpp

1#include "stdio.h" 2#include "Windows.h" 3#include "OpenAL/include/al.h" 4#include "OpenAL/include/alc.h" 5 6#define HEADER_SIZE ((int)44) 7 8// フォーマットを取得 9ALenum getFormat(int wavChannels, int wavBit) 10{ 11 ALenum format = 0; 12 if (wavChannels == 1) { 13 if (wavBit == 8) { 14 format = AL_FORMAT_MONO8; 15 } 16 else if (wavBit == 16) { 17 format = AL_FORMAT_MONO16; 18 } 19 } 20 else if (wavChannels == 2) { 21 if (wavBit == 8) { 22 format = AL_FORMAT_STEREO8; 23 } 24 else if (wavBit == 16) { 25 format = AL_FORMAT_STEREO16; 26 } 27 } 28 return format; 29} 30 31// ########## チャンクデータ 32struct Chunk_Data { 33 34public: 35 36 char riff[5]; // "RIFF"(固定) 37 int chunk_size; //チャンクのサイズ 38 int format; //フォーマット 39 ALenum alenumFormat; //alenumフォーマット 40 char fmt[5]; // "fmt"(固定) 41 int fmt_chunk_byte; //fmtチャンクのバイト数 42 short sound_format; //音フォーマット 43 short channel; //チャンネル数 44 int sample_rate; //サンプリング周波数 45 int byte_per_sec; //1秒あたりのバイトの平均 46 short block_size; //ブロックサイズ 47 short bit_per_sample; //1サンプルに必要なビット数 48 49 short extension_size; //拡張パラメーター サイズ 50 unsigned char* extension_data = nullptr; //拡張パラメーター 51 52 char sub_chunck[5]; // "data"(固定) 53 long long int DataSize; //波形データのバイト数 54 int all_DataSize; //ファイル全体のサイズ 55 int playTime; 56 57 58 unsigned char* Data = nullptr; //音データ 59}; 60 61 62// バイナリを各型に変換 63int convInt(unsigned char* header, int start) 64{ 65 int ret = (header[start + 3] << 24) | (header[start + 2] << 16) | (header[start + 1] << 8) | (header[start + 0]); 66 67 return ret; 68} 69 70short convShort(unsigned char* header, int start) 71{ 72 int ret = (header[start + 1] << 8) | (header[start + 0]); 73 return ret; 74} 75 76char convChar(unsigned char* header, int start) 77{ 78 char ret = header[start]; 79 return ret; 80} 81 82// 拡張パラメータを処理する。 83void extention_process(unsigned char* header,const int &size,unsigned char* data,const int &format) 84{ 85 86} 87 88int main() 89{ 90 const char* file = "sample2.wav"; //ファイル名指定 91// const char* file = "sample.wav"; //ファイル名指定 92 FILE* fp = NULL; //ファイルポインタ 93 94 struct Chunk_Data chunk; 95 96 97 ALuint source; 98 ALuint buffer; 99 100 // デバイスを開く 101 ALCdevice* device = alcOpenDevice(NULL); 102 if (!device) 103 { 104 printf("デバイスを作成出来ません。\n"); 105 } 106 107 ALCcontext* context = alcCreateContext(device,NULL); 108 if (!context) 109 { 110 printf("コンテキストを作成出来ません。\n"); 111 } 112 113 alcMakeContextCurrent(context); // コンテキストを適用 114 115 alGenSources(1, &source); // 116 alGenBuffers(1, &buffer); // 117 118 //ファイルを開く 119 fopen_s(&fp, file, "rb"); 120 if (!fp) { 121 printf("ファイルが開けません。\n"); 122 } 123 124////////////////////////////////////////////////////////////////////////////////// 125 126 unsigned char* Data;//音データーのサイズ 127 unsigned char header[HEADER_SIZE] = { 0 }; //ヘッダーサイズ 128 129 130 fread(header, 1, HEADER_SIZE, fp); //チャンクデータを読み込む 131 132 133 //riff識別子4バイト 134 chunk.riff[0] = convChar(header, 0); 135 chunk.riff[1] = convChar(header, 1); 136 chunk.riff[2] = convChar(header, 2); 137 chunk.riff[3] = convChar(header, 3); 138 chunk.riff[4] = '\0'; 139 140 chunk.chunk_size = convInt(header, 4); //チャンクサイズ 141 142 chunk.format = convInt(header, 8); //フォーマット 143 144 //fmt識別子 145 chunk.fmt[0] = convChar(header, 12); 146 chunk.fmt[1] = convChar(header, 13); 147 chunk.fmt[2] = convChar(header, 14); 148 chunk.fmt[3] = convChar(header, 15); 149 chunk.fmt[4] = '\0'; 150 151 chunk.fmt_chunk_byte = convInt(header, 16); //fmt識別子のチャンクバイト数 152 153 chunk.sound_format = convShort(header,20); //音フォーマット 154 chunk.channel = (int)convShort(header, 22); //チャンネル数 155 156 chunk.sample_rate = convInt(header, 24); //サンプリング周波数 157 chunk.byte_per_sec = convInt(header, 28); //1秒あたりのバイトの平均 158 159 160 chunk.block_size = convShort(header, 32); //ブロックサイズ 161 chunk.bit_per_sample = convShort(header,34); //1サンプルに必要なビット数 162 163 164 //PCMかどうかを判定 165 if ((int)chunk.sound_format != 1) 166 { 167 printf("PCMデータではありません。フォーマット処理未実装: 0x%x \n", chunk.sound_format); 168 chunk.extension_size = convShort(header, 36); //拡張サイズ 169 chunk.extension_data = nullptr; //拡張データ 170 171 extention_process(header, chunk.extension_size, chunk.extension_data, chunk.sound_format); //フォーマット処理 172 } 173 else { 174 // PCMの場合 175// chunk.extension_size = convShort(header,36); //拡張サイズ 176 chunk.extension_data = nullptr; //拡張データ 177 178 chunk.sub_chunck[0] = convChar(header, 36); 179 chunk.sub_chunck[1] = convChar(header, 37); 180 chunk.sub_chunck[2] = convChar(header, 38); 181 chunk.sub_chunck[3] = convChar(header, 39); 182 chunk.sub_chunck[4] = '\0'; 183 184 chunk.DataSize = convInt(header,40); 185 186 chunk.all_DataSize = chunk.DataSize + 40; 187 188 } 189 190 191 chunk.alenumFormat = getFormat(chunk.channel, chunk.bit_per_sample); 192 chunk.Data = new unsigned char[chunk.DataSize]{ 0 }; // 音データを作る 193 fread(chunk.Data, 1, chunk.DataSize, fp); 194 195///////////////////////////////////////////////////////////////////////////////////////////////// 196 197 198 printf("### チャンク情報 ###\n\n"); 199 printf("# チャンク ID: 0x%x%x%x%x\n", chunk.riff[0], chunk.riff[1], chunk.riff[2], chunk.riff[3]); 200 printf("# チャンクサイズ: %d\n", chunk.chunk_size); 201 printf("# フォーマット: %d\n", chunk.format); 202 203 printf("# fmt ID: 0x%x%x%x%x\n", chunk.fmt[0], chunk.fmt[1], chunk.fmt[2], chunk.fmt[3]); 204 205 printf("# fmtチャンクのバイト数: %d\n", chunk.fmt_chunk_byte); 206 printf("# 音フォーマット: 0x%x\n", chunk.sound_format); 207 printf("# チャンネル数: %d\n", (int)chunk.channel); 208 printf("# サンプリング周波数: %d\n", chunk.sample_rate); 209 printf("# 1秒あたりバイト数の平均: %d\n", chunk.byte_per_sec); 210 printf("# ブロックサイズ: %d\n", chunk.block_size); 211 printf("# 1サンプルに必要なビット数: %d\n\n\n", chunk.bit_per_sample); 212 213 if (chunk.sound_format == 1) 214 { 215 printf("# 拡張パラメーター サイズ: 未使用 \n"); 216 printf("# 拡張パラメーター: 未使用 \n"); 217 218 219 }else 220 { 221 printf("# 拡張パラメーター サイズ: %d\n", chunk.extension_size); 222 printf("# 拡張パラメーター: 存在する。\n"); 223 } 224 225 printf("# サブチャンク識別子: 0x%x%x%x%x\n", chunk.sub_chunck[0], chunk.sub_chunck[1], chunk.sub_chunck[2], chunk.sub_chunck[3]); // "data"(固定) 226 int time = chunk.DataSize / (chunk.byte_per_sec); //再生時間 227 228 229 230 printf("### ファイル情報 ###\n\n"); 231 232 printf("# 音データのサイズ: %lld\n", chunk.DataSize); // 音データ 233 printf("# ファイルのサイズ: %d\n", chunk.all_DataSize); // ファイルデータ 234 printf("# 再生時間: %d\n", time); 235 236 alBufferData(buffer, chunk.alenumFormat, chunk.Data, chunk.DataSize, chunk.sample_rate); 237 alSourcei(source, AL_BUFFER, buffer); 238 alSourcePlay(source); 239 240 241 Sleep(10000); 242 243 244 return 0; 245}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

thkana

2021/01/16 13:36

バイナリエディタでファイルの40byte目からのデータを確認してみる、というのもやるべき一つかも(もちろん自分でダンプするプログラムを書いてもいい、というかそれくらいできなきゃ)。 昔はstirling(https://www.vector.co.jp/soft/win95/util/se079072.html)とかだったけど、最近はもっといいのが出てたりするかしら?
退会済みユーザー

退会済みユーザー

2021/01/17 01:32 編集

開きましたが出てきません。どうすればいいのでしょうか また5秒程度の短い音楽ファイルでは正常に表示されるのですがなぜファイルの大きさでバグするのでしょうか?ここが最大の謎です。
thkana

2021/01/17 01:57

「何を」開いて「何が」出てこなかったのでしょう?
退会済みユーザー

退会済みユーザー

2021/01/17 02:10

バイナリエディタでヘッダ見れば、何バイト目に何のチャンクがあるかは明白でしょう。それで判らないのなら、無理なので諦めてください。
fumu7

2021/01/17 02:29

「222と表示される」というのは、何をした時に、何に表示されるというのですか?
guest

回答3

0

前回の回答した内容が、全くコードに反映されてない気がするんですが。
https://teratail.com/questions/316251
チャンクのIDとサイズを精査せずに、ヘッダサイズ決め打ちでデータ取得してれば、想定外のチャンクが存在した場合に正しいデータが取得出来ないのは当たり前です。waveフォーマットのチャンクの数は変動します。

投稿2021/01/17 02:03

編集2021/01/17 02:07
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

データをバイナリで見てみて、なにも思いませんか? なんのために「バイナリで見る」提案をされたと思っているのでしょう...

40バイト目からのデータがDE 00 00 00となっていますね。この値をconvInt関数にかければ222が得られます。

ここからわかることは、「ファイルサイズを求める考え方が間違っている」ということです。

先に言っておきますが「どうすればファイルサイズが求まるのか」はあなたが調べることです。私は知らないので、聞かないでください。(チャンクを全部辿ってそのサイズを合計する、とかなのかと想像はしますが)

投稿2021/01/17 02:02

thkana

総合スコア7703

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

thkana

2021/01/17 02:15

聞かないで、といいつつちょろっとwavのファイルフォーマットを覗いてみると、つまり先頭のRIFFが全体のコンテナになっているから、ファイルサイズを知りたければRIFFチャンク(と言っていいのか?)のサイズを調べればそれでよい、という話? それだとチャンク本体0x02d009da=47188442 +ヘッダ分8で計算が合うね。
退会済みユーザー

退会済みユーザー

2021/01/17 02:29 編集

RIFFチャンクはチャンクのヘッダサイズを引いたファイル全体のサイズで、音声データのサイズはdataチャンクのサイズを取ります。
guest

0

ちょっと頭がこんがらがってきたので一旦なかったことに。大変失礼しました。

投稿2021/01/16 10:31

編集2021/01/16 11:51
A_kirisaki

総合スコア2853

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/01/16 10:32

変更してみましたが同じです。だめでした。
Zuishin

2021/01/16 10:56

回答がつくまで同じ質問を書いては消し書いては消すのをやめなさい。
thkana

2021/01/16 11:42

> << 4096 4096ビットシフト?
A_kirisaki

2021/01/16 11:48

あっちがう、頭がこんがらがってきてしまった
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問