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

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

詳細はこちら
C++

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

Q&A

解決済

1回答

2076閲覧

.wavファイルがリニアPCMじゃない場合の拡張データの読み込み方法が正しいのか知りたい。

退会済みユーザー

退会済みユーザー

総合スコア0

C++

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

0グッド

0クリップ

投稿2021/01/15 13:02

提示コードですが/////コメント部の内部のコードの音声フォーマットが2の場合の処理ですがこの処理は正しいのでしょうか?
サイズがわからないためサイズ分for文を回しましたがこの処理が正しいのか知りたいです。

cpp

1#include "stdio.h" 2#include "OpenAL/include/al.h" 3#include "OpenAL/include/alc.h" 4 5#define HEADER_SIZE ((int)44) 6 7int convInt(unsigned char* header, int start) 8{ 9 int ret = (header[start + 3] << 24) | (header[start + 2] << 16) | (header[start + 1] << 8) | (header[start + 0]); 10 11 return ret; 12} 13 14short convShort(unsigned char* header, int start) 15{ 16 int ret = (header[start + 1] << 8) | (header[start + 0]); 17 return ret; 18} 19 20char convChar(unsigned char* header, int start) 21{ 22 char ret = header[start]; 23 return ret; 24} 25 26 27int main() 28{ 29 const char* file = "sample.wav"; //ファイル名指定 30 FILE* fp = NULL; 31 32 ALuint source; 33 ALuint buffer; 34 35 // デバイスを開く 36 ALCdevice* device = alcOpenDevice(NULL); 37 if (!device) 38 { 39 printf("デバイスを作成出来ません。\n"); 40 } 41 42 ALCcontext* context = alcCreateContext(device,NULL); 43 if (!context) 44 { 45 printf("コンテキストを作成出来ません。\n"); 46 } 47 48 alcMakeContextCurrent(context); // コンテキストを適用 49 50 alGenSources(1, &source); // 51 alGenBuffers(1, &buffer); // 52 53 //ファイルを開く 54 fopen_s(&fp, file, "rb"); 55 if (!fp) { 56 printf("ファイルが開けません。\n"); 57 } 58 59 // ########## チャンクデータ 60 char riff[5]; // "RIFF"(固定) 61 int chunk_size; //チャンクのサイズ 62 int format; //フォーマット 63 char fmt[5]; // "fmt"(固定) 64 int fmt_chunk_byte; //fmtチャンクのバイト数 65 short sound_format; //音フォーマット 66 short channel; //チャンネル数 67 int sample_rate; //サンプリング周波数 68 int byte_per_sec; //1秒あたりのバイトの平均 69 short block_size; //ブロックサイズ 70 short bit_per_sample; //1サンプルに必要なビット数 71 short extension_size; //拡張パラメーター サイズ 72 unsigned char* extension_data = nullptr; //拡張パラメーター 73 char sub_chunck[5]; // "data"(固定) 74 int sub_chunk_size; //波形データのバイト数 75 76 unsigned char* Data;//音データーのサイズ 77 unsigned char header[HEADER_SIZE] = { 0 }; //ヘッダーサイズ 78 79 80 fread(header, 1, HEADER_SIZE, fp); //チャンクデータを読み込む 81 82 83 //riff識別子4バイト 84 riff[0] = convChar(header, 0); 85 riff[1] = convChar(header, 1); 86 riff[2] = convChar(header, 2); 87 riff[3] = convChar(header, 3); 88 riff[4] = '\0'; 89 90 chunk_size = convInt(header, 4); //チャンクサイズ 91 92 format = convInt(header, 8); //フォーマット 93 94 //fmt識別子 95 fmt[0] = convChar(header, 12); 96 fmt[1] = convChar(header, 13); 97 fmt[2] = convChar(header, 14); 98 fmt[3] = convChar(header, 15); 99 fmt[4] = '\0'; 100 101 fmt_chunk_byte = convInt(header, 16); //fmt識別子のチャンクバイト数 102 103 sound_format = convShort(header,20); //音フォーマット 104 channel = convShort(header, 22); //チャンネル数 105 106 sample_rate = convInt(header, 24); //サンプリング周波数 107 byte_per_sec = convInt(header, 28); //1秒あたりのバイトの平均 108 109 110 block_size = convShort(header, 32); //ブロックサイズ 111 bit_per_sample = convShort(header,34); //1サンプルに必要なビット数 112//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 113 if (sound_format != 1) { 114 printf("# 音声フォーマット 2 \n"); 115 116 extension_size = convShort(header, 36); //拡張パラメーター サイズ 117 extension_data = new unsigned char[extension_size] { '\0' }; //拡張パラメーター 118 int a = 36 + 2; 119 for (int i = 0; i < extension_size; i++) 120 { 121 extension_data[i] = convChar(header, a + i); 122 } 123 124 125 126 // "data"(固定) 127 sub_chunck[0] = convChar(header, a + extension_size + 1); 128 sub_chunck[1] = convChar(header, a + extension_size + 2); 129 sub_chunck[2] = convChar(header, a + extension_size + 3); 130 sub_chunck[3] = convChar(header, a + extension_size + 4); 131 sub_chunck[4] = '\0'; 132 133 sub_chunk_size = convInt(header, a + extension_size + 4 ); //波形データのバイト数 134 135 } 136 else { 137 // 音声フォーマット1 138 printf("# 音声フォーマット 1 \n"); 139 140 141 // "data"(固定) 142 sub_chunck[0] = convChar(header, 36); 143 sub_chunck[1] = convChar(header, 37); 144 sub_chunck[2] = convChar(header, 38); 145 sub_chunck[3] = convChar(header, 39); 146 sub_chunck[4] = '\0'; 147 148 sub_chunk_size = convInt(header, 40); //波形データのバイト数 149 150 } 151 152///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 153 printf("チャンク識別子: %s\n", riff); 154 printf("チャンクサイズ: %d\n", chunk_size); 155 printf("フォーマット: %d\n", format); 156 printf("fmt識別子: %s\n", fmt); 157 printf("fmtチャンクのバイト数: %d\n", fmt_chunk_byte); 158 printf("音フォーマット: %d\n", sound_format); 159 printf("チャンネル数: %d\n", channel); 160 printf("サンプリング周波数: %d\n", sample_rate); 161 printf("1秒あたりバイト数の平均: %d\n", byte_per_sec); 162 printf("ブロックサイズ: %d\n", block_size); 163 printf("1サンプルに必要なビット数: %d\n", bit_per_sample); 164 165 if (sound_format == 1) 166 { 167 printf("拡張パラメーター サイズ: 未使用 \n"); 168 printf("拡張パラメーター: 未使用 \n"); 169 }else 170 { 171 printf("拡張パラメーター サイズ: %d\n", extension_size); 172 printf("拡張パラメーター: %d\n", extension_data); 173 } 174 175 printf("サブチャンク識別子: %s\n", sub_chunck); // "data"(固定) 176 printf("サブチャンクサイズ(波形データの総数): %d\n",sub_chunk_size); // 177 return 0; 178}

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

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

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

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

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

guest

回答1

0

ベストアンサー

正しいか正しくないかで言えば、正しくないです。
チャンクは"RIFF" "fmt " "data"の3種類だけとは限らないので、不要なチャンクがあったら読み飛ばす必要があるのと、PCM以外のフォーマットなら、適切なデコード処理をしてPCMに戻す必要があります。(普通はACMや外部ライブラリ等を使用する)

投稿2021/01/15 15:31

編集2021/01/16 01:11
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

退会済みユーザー

退会済みユーザー

2021/01/16 00:49 編集

まーた新しい質問立てて突っ込んだら削除してるし… 突っ込まれるのが嫌なら、きちんと調査してから質問したら?外部サイトのリンク貼るだけで中身読んで理解してないのは、調査したとは言わない。
退会済みユーザー

退会済みユーザー

2021/01/16 01:21

不要なチャンクを読み飛ばすにはどうすればいいのでしょうか?
退会済みユーザー

退会済みユーザー

2021/01/16 01:23 編集

チャンクIDを検索して、必要なチャンクだけ拾えばいいと思いますが。
退会済みユーザー

退会済みユーザー

2021/01/16 01:33 編集

あと、PCM以外のフォーマットに対応するつもりであれば、最低限対応する音声フォーマットとそのデコードについて自力調査するスキルが無いと無理なので、それが出来ないのであればやめておいた方がいいと思われます。 WAVEフォーマットは腐るほどあります。https://docs.rs/winapi/0.2.7/i686-pc-windows-gnu/winapi/mmreg/index.html
退会済みユーザー

退会済みユーザー

2021/01/16 01:34

質問ですがPCMデータは一般的なのでしょうか?
退会済みユーザー

退会済みユーザー

2021/01/16 01:35

一般的とはどういう意味でしょうか?
退会済みユーザー

退会済みユーザー

2021/01/16 01:51

普通はPCMなのかどうかです mp3 flacなどは圧縮してありますがそのまたさらに圧縮という意味なのでしょうか?
退会済みユーザー

退会済みユーザー

2021/01/16 02:12 編集

短い効果音程度ならPCMを使ってもいいと思いますが、PCMはサイズが大きいので、最近は他の圧縮音声を使うケースが多いのでは。音楽など長い音声データは、通常は圧縮音声をストリーミング再生すると思います。(全部メモリに読むと、とんでもないサイズになるため)
退会済みユーザー

退会済みユーザー

2021/01/16 02:19

PCMとは.wavでの圧縮方式なのでしょうか?
退会済みユーザー

退会済みユーザー

2021/01/16 02:29 編集

圧縮方法ではなく、音声をデジタルで表現するための方式です。PCMでググった方が早いと思います
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問