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

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

詳細はこちら
C++

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

Q&A

解決済

2回答

6094閲覧

音声ファイルの再生時間を算出したい。

退会済みユーザー

退会済みユーザー

総合スコア0

C++

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

0グッド

0クリップ

投稿2021/01/15 08:40

編集2021/01/16 07:30

提示コードの///////内部のコードですが。再生時間を取得する方法が知りたいです。どうすればいいのでしょか?

参考サイト: https://www.youfit.co.jp/archives/1418
再生時間5秒です
イメージ説明

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

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

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

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

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

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

guest

回答2

0

4固定はあまり良くない実装だと思います。
ある程度音声フォーマットが固定のものという前提を置いた計算になっているからです。

通常のWaveフォーマットヘッダは以下の情報が含まれます。

C++

1typedef struct { 2 uint16_t wFormatTag; // format type 3 uint16_t nChannels; // number of channels (1:mono, 2:stereo) 4 uint32_t nSamplesPerSec; // sample rate 5 uint32_t nAvgBytesPerSec; // for buffer estimation 6 uint16_t nBlockAlign; // block size of data 7 uint16_t wBitsPerSample; // number of bits per sample of mono data 8 uint16_t cbSize; // extra information 9} WAVEFORMATEX;

nChannelsがチャネル数
nSamplesPerSecが一秒間に何サンプル取得するか
wBitsPerSampleは1チャンネルのサンプルあたりのビット数
要は一サンプルをshort(16bitの数値範囲)で表現するのか、32bitなのかとか
この情報と、音声データサイズから、音声データの時間が換算できるようになります。

C++

1size/(nSamplesPerSec*wBitsPerSample*nChannels) 2

4ということは、shortで2チャンネルを前提としていると思われます。

投稿2021/01/15 09:09

t_obara

総合スコア5488

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

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

退会済みユーザー

退会済みユーザー

2021/01/16 07:24 編集

提示コードと質問タイトルを編集しました。 ///コメント内部のコードですが回答通りに実装すると値が0になってしまうのですがなぜでしょうか?
guest

0

ベストアンサー

波形データ/ 一秒間の平均バイト数 で算出出来ました。

cpp

1 int r2 = chunk.DataSize / (chunk.byte_per_sec); 2

投稿2021/01/16 08:03

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問