TNB Library
TnbWaveFile.h
[詳解]
1#pragma once
11#include <TnbMap.h>
12#include <TnbConstFileMapping.h>
13#include <TnbDummyCollection.h>
15#include <mmsystem.h>
16
17
18
19//TNB Library
20namespace TNB
21{
22
23
24
35class CWaveFormat : public WAVEFORMATEX
36{
37public:
38
46 CWaveFormat(DWORD samplesPerSec = 44100, WORD bitsPerSample = 16, WORD channels = 2)
47 {
48 wFormatTag = WAVE_FORMAT_PCM;
49 cbSize = sizeof(WAVEFORMATEX);
50 Set(samplesPerSec, bitsPerSample, channels);
51 }
52
57 CWaveFormat(const WAVEFORMATEX& f)
58 {
59 WAVEFORMATEX* P = this;
60 *P = f;
61 }
62
70 void Set(DWORD samplesPerSec, WORD bitsPerSample, WORD channels)
71 {
72 nSamplesPerSec = samplesPerSec;
73 wBitsPerSample = bitsPerSample;
74 nChannels = channels;
75 nBlockAlign = static_cast<WORD>(nChannels * wBitsPerSample / 8);
76 nAvgBytesPerSec = nSamplesPerSec * nBlockAlign;
77 }
78
84 DWORD CalcTime(size_t samples) const
85 {
86 ULONGLONG r = samples;
87 r *= 1000;
88 return static_cast<DWORD>((r + nSamplesPerSec - 1) / nSamplesPerSec);
89 }
90
96 size_t CalcSamples(DWORD time) const
97 {
98 ULONGLONG r = time;
99 r *= nSamplesPerSec;
100 return static_cast<size_t>(r / 1000);
101 }
102};
103
104
105
126{
127public:
128
131 {
132 FOURCC type;
133 LONG length;
134 };
135
145 {
146 public:
147
151 void Empty(void)
152 {
153 m_map.RemoveAll();
154 }
155
162 {
164 v.Copy(m_map.GetKeysAdapter());
165 return v;
166 }
167
175 bool Has(FOURCC cc) const
176 {
177 return m_map.HasKey(cc);
178 }
179
188 bool Get(CAscii& _str, FOURCC cc) const
189 {
190 if ( m_map.HasKey(cc) )
191 {
192 _str = m_map[cc];
193 return true;
194 }
195 return false;
196 }
197
204 void Set(FOURCC cc, LPCTSTR lpsz)
205 {
206 m_map[cc] = lpsz;
207 }
208
214 CByteVector Make(void) const
215 {
216 CByteVector vb;
217 vb.AddElements(4, reinterpret_cast<const BYTE*>("INFO"));
218 loop ( i, m_map.GetSize() )
219 {
220 FOURCC cc = m_map.At(i).first;
221 const CAscii& s = m_map.At(i).second;
222 DWORD len = s.GetLength() + 1;
223 vb.AddElements(4, reinterpret_cast<const BYTE*>(&cc));
224 vb.AddElements(4, reinterpret_cast<const BYTE*>(&len));
225 vb.AddElements(len, reinterpret_cast<const BYTE*>(s.operator LPCSTR()));
226 if ( (len & 1) != 0 )
227 {
228 vb.Add(0);
229 }
230 }
231 return vb;
232 }
233
242 {
243 m_map.RemoveAll();
244 size_t sz = 0;
245 DWORD pos = 0;
246 FOURCC type;
247 sz = c.GetElements(sizeof(FOURCC), reinterpret_cast<BYTE*>(&type), pos);
248 if ( sz != sizeof(FOURCC) )
249 {
250 return false;
251 }
252 pos += sz;
253 if ( type != MAKEFOURCC('I', 'N', 'F', 'O') )
254 {
255 return false;
256 }
257 TChunkHeader chunk;
258 while ( pos < c.GetSize() )
259 {
260 sz = c.GetElements(sizeof(chunk), reinterpret_cast<BYTE*>(&chunk), pos);
261 if ( sz != sizeof(chunk) )
262 {
263 return false;
264 }
265 pos += sz;
266 size_t len = chunk.length;
267 if ( (len & 1) != 0 )
268 {
269 len ++; //偶数にする
270 }
271 CAscii& a = m_map[chunk.type];
272 sz = c.GetElements(len, reinterpret_cast<BYTE*>(a.GetBuffer(len + 1)), pos);
273 if ( sz != len )
274 {
275 return false;
276 }
277 pos += sz;
278 a.ReleaseBuffer();
279 }
280 return true;
281 }
282
291 bool Analyze(size_t size, const BYTE* P)
292 {
293 return Analyze(CConstAdapterT<BYTE>(size, P));
294 }
295
296 private:
298 };
299
300
301 //--------------
302
303
305 CWaveFile(void) : m_dataSize(0), m_dataOffset(0), m_adapter(NULL, 0)
306 {
307 }
308
311 {
312 Close();
313 }
314
321 bool IsOpened(void) const
322 {
323 return m_file.IsOpened();
324 }
325
327 void Close(void)
328 {
329 m_file.Close();
330 m_file16.Close();
331 m_chunkMap.RemoveAll();
332 m_refData.RemoveAll();
333 m_dataOffset = 0;
334 m_dataSize = 0;
335 }
336
345 bool Open(LPCTSTR fileName, const WAVEFORMATEX& format)
346 {
347 Close();
348 m_format = format;
349 if ( ! m_file.Open(fileName) )
350 {
351 return false;
352 }
353 if ( ! m_file16.Open(fileName) )
354 {
355 return false;
356 }
357 m_dataOffset = 0;
358 m_dataSize = m_file.GetSize();
359 return true;
360 }
361
369 bool Open(LPCTSTR fileName)
370 {
371 Close();
372 if ( ! m_file.Open(fileName) )
373 {
374 return false;
375 }
376 INDEX pos = 0;
377 TChunkHeader fileChunk;
378 pos += m_file.GetElements(sizeof(fileChunk), reinterpret_cast<BYTE*>(&fileChunk), pos);
379 FOURCC riffType;
380 pos += m_file.GetElements(sizeof(riffType), reinterpret_cast<BYTE*>(&riffType), pos);
381 if ( fileChunk.type == FC_RIFF && fileChunk.length <= ToInt(m_file.GetSize()) && riffType == FC_WAVE )
382 {
383 while( pos < m_file.GetSize() )
384 {
385 TChunkHeader chunk;
386 pos += m_file.GetElements(sizeof(chunk), reinterpret_cast<BYTE*>(&chunk), pos);
387 if ( chunk.type == FC_FMT )
388 {
389 m_file.GetElements(sizeof(m_format), reinterpret_cast<BYTE*>(&m_format), pos);
390 WORD bps = m_format.wBitsPerSample;
391 if ( bps != 8 && bps != 16 )
392 {
393 break;
394 }
395 if ( m_format.wFormatTag != WAVE_FORMAT_PCM )
396 {
397 break;
398 }
399 if ( m_format.nChannels != 1 && m_format.nChannels != 2 )
400 {
401 break;
402 }
403 m_format.cbSize = 0;
404 }
405 else if ( chunk.type == FC_DATA )
406 {
407 m_dataOffset = pos;
408 m_dataSize = chunk.length;
409 }
410 else
411 {
412 TChunkMap cm;
413 cm.offset = pos;
414 cm.size = chunk.length;
415 m_chunkMap[chunk.type] = cm;
416 }
417 if ( chunk.length == 0 )
418 {
419 break;
420 }
421 pos += chunk.length;
422 }
423 if ( pos >= m_file.GetSize() )
424 {
425 if ( m_file16.Open(fileName, m_dataOffset, m_dataSize / sizeof(short)) )
426 {
427 return true;
428 }
429 }
430 }
431 Close();
432 return false;
433 }
434
439 const CWaveFormat& RefFormat(void) const
440 {
441 return m_format;
442 }
443
448 size_t GetSamples(void) const
449 {
450 if ( m_format.nBlockAlign == 0 )
451 {
452 return 0;
453 }
454 return m_dataSize / m_format.nBlockAlign;
455 }
456
461 DWORD GetTotalTime(void) const
462 {
463 if ( m_format.nBlockAlign == 0 || m_format.nSamplesPerSec == 0 )
464 {
465 return 0;
466 }
467 ULONGLONG r = (m_dataSize / m_format.nBlockAlign);
468 r *= 1000;
469 return static_cast<DWORD>((r + m_format.nSamplesPerSec - 1) / m_format.nSamplesPerSec);
470 }
471
476 size_t GetDataSize(void) const
477 {
478 return m_dataSize;
479 }
480
486 const BYTE* RefData(INDEX i = 0) const
487 {
488 if ( m_refData.IsEmpty() )
489 {
490 m_refData.Copy(GetByteData());
491 }
492 return m_refData.ReferBuffer() + i;
493 }
494
502 {
503 m_adapter = CConstOffsetAdapterT<BYTE>(&m_file, m_dataOffset, m_dataSize);
504 return m_adapter;
505 }
506
514 {
515 return m_file16;
516 }
517
525 const IConstCollectionT<BYTE>& GetChunk(FOURCC cc) const
526 {
527 if ( m_chunkMap.HasKey(cc) )
528 {
529 m_adapter = CConstOffsetAdapterT<BYTE>(&m_file, m_chunkMap[cc].offset, m_chunkMap[cc].size);
530 return m_adapter;
531 }
532 return m_nullCollection;
533 }
534
542 {
543 const IConstCollectionT<BYTE>& c = GetChunk(MAKEFOURCC('L','I','S','T'));
544 if ( c.GetSize() > 0 )
545 {
546 return _lic.Analyze(c);
547 }
548 return false;
549 }
550
561 static size_t MakeWaveHeader(CWorkMem& _head, int channels, long rate, WORD bit, size_t dataSize, size_t extendSize = 0)
562 {
563 _head.Resize(sizeof(TWaveFileHeader));
564 TWaveFileHeader* P = reinterpret_cast<TWaveFileHeader*>(_head.Ref());
565 P->fileChunk.type = FC_RIFF;
566 P->fileChunk.length = dataSize + extendSize + sizeof(TWaveFileHeader) - 8;
567 P->fileType = FC_WAVE;
568 P->format.wf.wFormatTag = WAVE_FORMAT_PCM;
569 P->format.wf.nChannels = static_cast<WORD>(channels);
570 P->format.wf.nSamplesPerSec = rate;
571 P->format.wBitsPerSample = bit;
572 P->format.wf.nBlockAlign = static_cast<WORD>(channels * bit / 8);
573 P->format.wf.nAvgBytesPerSec = channels * bit / 8 * rate;
574 P->formatChunk.type = FC_FMT;
575 P->formatChunk.length = sizeof(PCMWAVEFORMAT);
576 P->dataChunk.type = FC_DATA;
577 P->dataChunk.length = dataSize;
578 return sizeof(TWaveFileHeader);
579 }
580
581private:
583 enum
584 {
585 FC_RIFF = MAKEFOURCC('R', 'I', 'F', 'F'),
586 FC_WAVE = MAKEFOURCC('W', 'A', 'V', 'E'),
587 FC_FMT = MAKEFOURCC('f', 'm', 't', ' '),
588 FC_DATA = MAKEFOURCC('d', 'a', 't', 'a'),
589 };
591 struct TWaveFileHeader
592 {
593 TChunkHeader fileChunk;
594 FOURCC fileType;
595 TChunkHeader formatChunk;
596 PCMWAVEFORMAT format;
597 TChunkHeader dataChunk;
598 };
600 struct TChunkMap
601 {
602 size_t size;
603 INDEX offset;
604 };
605
606 CWaveFormat m_format;
607 CConstFileMapping m_file;
609 size_t m_dataSize;
610 INDEX m_dataOffset;
611 CMapT<FOURCC, TChunkMap> m_chunkMap;
612 mutable CByteVector m_refData;
613 mutable CConstOffsetAdapterT<BYTE> m_adapter;
614 CDummyCollectionT<BYTE> m_nullCollection;
615};
616
617
618
619}; // TNB
620
情報群管理アダプタ関係のヘッダ
ファイルマッピング処理関係のヘッダ
#define loop(VAR, CNT)
loop構文.
Definition: TnbDef.h:343
ダミーコレクション関係のヘッダ
マップ型情報管理関係のヘッダ
情報参照アダプタテンプレート
virtual size_t GetSize(void) const
[取得] 要素数取得.
bool Open(LPCTSTR lpszName, LONGLONG offset=0, size_t size=INVALID_SIZE)
[操作] オープン.
bool IsOpened(void) const
[確認] オープン確認.
void Close(void)
[操作] クローズ.
[ETC] コピー不可能スーパークラス.
Definition: TnbDef.h:599
マップ型情報管理テンプレート
Definition: TnbMap.h:66
virtual bool RemoveAll(void)
[削除] すべてのキーと値を削除
Definition: TnbMap.h:434
bool HasKey(INK key) const
[確認] キー有無
Definition: TnbMap.h:589
void ReleaseBuffer(void)
[操作] 割り当てたバッファを開放.
Definition: TnbStr.h:954
size_t GetLength(void) const
[取得] 文字列長
Definition: TnbStr.h:518
TYP * GetBuffer(size_t iLength=0)
[操作] 書き込みバッファ要求.
Definition: TnbStr.h:914
配列型情報管理テンプレート
Definition: TnbVector.h:75
virtual bool RemoveAll(void)
[削除] 空化
Definition: TnbVector.h:565
virtual size_t AddElements(size_t size, const TYP *P=NULL)
[追加] 複数要素追加.
Definition: TnbVector.h:456
virtual const TYP * ReferBuffer(void) const
[取得] データアドレス取得
Definition: TnbVector.h:664
virtual INDEX Add(const TYP &t)
[追加] 要素一つ追加.
Definition: TnbVector.h:383
LIST INFO チャンク管理
Definition: TnbWaveFile.h:145
bool Analyze(size_t size, const BYTE *P)
[解析] チャンクブロック解析.
Definition: TnbWaveFile.h:291
bool Analyze(const IConstCollectionT< BYTE > &c)
[解析] チャンクブロック解析.
Definition: TnbWaveFile.h:241
bool Has(FOURCC cc) const
[確認] タイプ確認.
Definition: TnbWaveFile.h:175
CVectorT< FOURCC > EnumType(void) const
[取得] タイプ一覧取得.
Definition: TnbWaveFile.h:161
void Empty(void)
[設定] 空化
Definition: TnbWaveFile.h:151
void Set(FOURCC cc, LPCTSTR lpsz)
[設定] 文字列取得.
Definition: TnbWaveFile.h:204
bool Get(CAscii &_str, FOURCC cc) const
[取得] 文字列取得.
Definition: TnbWaveFile.h:188
CByteVector Make(void) const
[作成] チャンクブロック作成.
Definition: TnbWaveFile.h:214
WAVEファイルクラス
Definition: TnbWaveFile.h:126
~CWaveFile(void)
デストラクタ
Definition: TnbWaveFile.h:310
bool Open(LPCTSTR fileName, const WAVEFORMATEX &format)
[設定] PCMファイルオープン
Definition: TnbWaveFile.h:345
bool GetListInfoChunk(CListInfoChunk &_lic) const
[取得] LIST,INFO チャンクデータ取得
Definition: TnbWaveFile.h:541
const IConstCollectionT< BYTE > & GetChunk(FOURCC cc) const
[取得] チャンクデータ取得.
Definition: TnbWaveFile.h:525
const BYTE * RefData(INDEX i=0) const
[取得] 波形データポインタ取得.
Definition: TnbWaveFile.h:486
size_t GetDataSize(void) const
[取得] 波形データサイズ取得.
Definition: TnbWaveFile.h:476
bool IsOpened(void) const
[確認] オープン確認.
Definition: TnbWaveFile.h:321
void Close(void)
[設定] クローズ
Definition: TnbWaveFile.h:327
size_t GetSamples(void) const
[取得] 波形データ数取得.
Definition: TnbWaveFile.h:448
CWaveFile(void)
コンストラクタ
Definition: TnbWaveFile.h:305
static size_t MakeWaveHeader(CWorkMem &_head, int channels, long rate, WORD bit, size_t dataSize, size_t extendSize=0)
[作成] Wavファイルヘッダ作成.
Definition: TnbWaveFile.h:561
const IConstCollectionT< short > & GetShortData(void) const
[取得] 16bit波形データ取得.
Definition: TnbWaveFile.h:513
const IConstCollectionT< BYTE > & GetByteData(void) const
[取得] 8bit波形データ取得.
Definition: TnbWaveFile.h:501
bool Open(LPCTSTR fileName)
[設定] WAVファイルオープン
Definition: TnbWaveFile.h:369
DWORD GetTotalTime(void) const
[取得] 波形データ時間取得.
Definition: TnbWaveFile.h:461
const CWaveFormat & RefFormat(void) const
[参照] Waveフォーマット参照
Definition: TnbWaveFile.h:439
WAVEフォーマットクラス
Definition: TnbWaveFile.h:36
size_t CalcSamples(DWORD time) const
[計算] 時間からサンプル数を計算
Definition: TnbWaveFile.h:96
DWORD CalcTime(size_t samples) const
[計算] サンプル数から時間を計算
Definition: TnbWaveFile.h:84
void Set(DWORD samplesPerSec, WORD bitsPerSample, WORD channels)
[設定] 設定
Definition: TnbWaveFile.h:70
CWaveFormat(DWORD samplesPerSec=44100, WORD bitsPerSample=16, WORD channels=2)
コンストラクタ
Definition: TnbWaveFile.h:46
CWaveFormat(const WAVEFORMATEX &f)
代入コンストラクタ
Definition: TnbWaveFile.h:57
void Resize(size_t l)
[設定] サイズ再設定
Definition: TnbDef.h:672
const TYP * Ref(void) const
[取得] ポインタ取得
Definition: TnbDef.h:712
int ToInt(LPCSTR lpsz, int iBase=10)
[変換] INT変換(ASCII/SJIS用).
Definition: TnbStrLib.h:367
TNB Library
Definition: TnbDoxyTitle.txt:2
チャンクヘッダー型
Definition: TnbWaveFile.h:131
virtual size_t Copy(const IConstCollectionT< TYP > &c)
[設定] コピー.
virtual size_t GetElements(size_t size, TYP *_P, INDEX offset=0) const
[取得] 複数要素取り出し.
bool IsEmpty(void) const
[確認] 要素の有無確認.
virtual size_t GetSize(void) const =0
[取得] 要素数取得.