#pragma once //CDDAのタイトル名の作成 CString __stdcall _FillCDDATitle(UINT track); //CDDAのパス名の作成 CString __stdcall _FillCDDAPath(TCHAR tchDrive,UINT track); //入力パス名を解析して、ドライブ名、トラック番号、拡張子文字列を取得します。 BOOL __stdcall _ParseCDDAPathName(LPCTSTR lpszPathName,TCHAR* pchDrive,UINT* lpTrack,CString& strExt); //指定パス名がCDROMドライブにあるかどうか検査します。 // lpszPathName:パス名 BOOL __stdcall _IsPathOnCDROMDrive(LPCTSTR lpszPathName); //引数で指定されたドライブ文字から順にドライブを検索して、 //CDROMのドライブ番号を取得します。 //TCHAR __stdcall _GetCDDrive(TCHAR tchFirst='C'); TCHAR __stdcall _FindCDDrive(TCHAR tchFirst='C'); //入力されたURLからHtmlテキストを受信します。 // lpszURL:問い合わせ先のURL文字列 // strHtmls:受信したHtmlテキストを格納するCStringクラス BOOL __stdcall _ReadHTTP(LPCTSTR lpszURL,CString& strHtmls); #include "WaveFile.h" #include "devioctl.h" #include "ntddcdrm.h" //CD-DAのセクタ当りのバイト数 #define RAW_SECTOR_SIZE 2352 //TRACKINFO構造体 typedef struct _TRACKINFO { BYTE Control; //トラックの属性(詳しくは「NCITS XXX T10/1363-D Revision - 02A //(Table 337 - Q Sub-channel control field)」を参照して下さい。) BYTE Addr; //Q Sub-Channel属性(詳しくは「NCITS XXX T10/1363-D Revision - 02A //(Table 336 - ADR Q Sub-channel field)」を参照して下さい。) BYTE Session; //所属するセッション番号 BYTE Address[4]; //開始セクタ番号 } TRACKINFO; //CDDA_TOC構造体 typedef struct _CDDA_TOC { BYTE FirstTrack; //開始トラック BYTE LastTrack; //終了トラック //トラック毎の情報 TRACKINFO TrackData[MAXIMUM_NUMBER_TRACKS]; } CDDA_TOC; //SESSIONINFO構造体 typedef struct _SESSIONINFO { BYTE SessionStart; //セッションの開始トラック番号 BYTE SessionStop; //セッションの終了トラック番号 DWORD SessionFAD; //セッションの開始セクタ番号 DWORD SessionEndFAD; //セッションの終了セクタ番号 } SESSIONINFO; //CDROM_SESSION構造体 typedef struct _CDROM_SESSION { BYTE FirstSession; //最初のセッション番号 BYTE LastSession; //最後のセッション番号 //セッション毎の情報 SESSIONINFO sessionInfo[MAXIMUM_NUMBER_TRACKS]; } CDROM_SESSION; //CDAFORMAT構造体 typedef struct tagCDAFORMAT{ WORD dwFileVersion; //cdaファイルバージョン。(今のところ1) WORD dwNumberOfTrack;//トラック番号 DWORD dwSerialNumber; //CDのシリアル番号 DWORD dwStartHsg; //開始セクタ番号 DWORD dwLengthHsg; //セクタ数 DWORD dwStartRedBook; //トラックの開始位置(レッドブックフォーマット) DWORD dwLengthRedBook;//トラックの長さ (レッドブックフォーマット) }CDAFORMAT,*LPCDAFORMAT; //CDDAFileクラス class CDDAFile : public CWaveFile { public: //コンストラクタ CDDAFile(CWnd* pWndOwner=NULL); //デストラクタ virtual ~CDDAFile(); //セクタ情報の初期化 void Init(); //演奏を停止して、セクタ情報を初期化します。 virtual void Delete(); //CDROMデバイスがオープンされているかどうか? virtual BOOL IsCDDAFile(){return (m_hDrive!=INVALID_HANDLE_VALUE);}; //読み込み中のデバイスハンドルの有効/無効を基底クラスに返します。 virtual BOOL IsOpen(){return (IsCDDAFile())? TRUE:CWaveFile::IsOpen();}; //CDDA音源データのストリーム読み込み virtual UINT StreamIn(LPVOID pBuffer,UINT nBufSize,UINT* pIndexSample); //一時停止します。 BOOL Pause(); //総演奏予定時間を取得します。 virtual UINT GetTotalTime(); //指定トラックの演奏時間文字列を返します。(mm:ss:dddms) CString GetTimeString(UINT nTrack); //CD-DA操作用関数----------------------------- //CDROMデバイスのオープン BOOL OpenCDDA(TCHAR tchDrive='C'); //CDROMデバイスのクローズ BOOL CloseCDDA(); //現在のセクタ位置からCD-DA音源データを読み込みます。 // pBuffer:音源データを書き込むバッファ // nBufSize:バッファサイズ(2352xNバイトになるようにして下さい。) UINT ReadCDDA(PBYTE pBuffer,UINT nBufSize); //ディスクチェンジ許可/禁止 BOOL PreventMediaRemoval(BOOL bPrevent); //CDROMのドアを閉める BOOL CloseDoor(); //CDROMのドアを開ける BOOL OpenDoor(); //アクセス可能かどうか BOOL IsReady(); //CDROMを停止する BOOL StopCDDA(); //CDDA_TOCとCDROM_SESSION構造体の読み込み BOOL ReadTOC(); //cdaファイルを開いてReadCDAFormat関数を呼び出します。 BOOL LoadCDA(LPCTSTR lpszFileName); //cdaファイルからCDAFORMAT構造体を読み込みます。 BOOL ReadCDAFormat(HMMIO hmmio); //CD-DAを開いてTOCとCDTextを読み込みます。 BOOL LoadCDDA(TCHAR tchDrive=0); //セッション範囲の取得 BOOL GetSessionRange(UINT* lpFirstSession,UINT* lpLastSession); //CDDAのセッション番号の取得 // 0:CDDAのセッションが見つからない BOOL GetCDDASession(){return m_sessionCDDA;}; //トラック範囲の取得 BOOL GetTrackRange(LPDWORD lpdwFirstTrack,LPDWORD lpdwLastTrack,UINT session=0); //セクター範囲の取得 BOOL GetSectorRange(UINT track,UINT* lpStartSector,UINT* lpStopSector); //CDテキスト------------------------------- //CDテキストを格納する文字列リスト // m_strText[ 0]:アルバム名[ 1]:演奏者 [ 2]:作詞家 [ 3]:作曲者 // [ 4]:編曲者 [ 5]:メッセージ[ 6]:ディスクID[ 7]:ジャンル // [ 8]:TOC情報 [ 9]:TOC情報2 [10]~[13]予約 // [14]:UPC EAN [15]:サイズ情報 CStringArray m_listCDText[16]; //CDテキストの読み込み BOOL ReadCDText(int retry=5); //CDテキストの有無 BOOL HasCDText(){return (m_listCDText[0].GetSize()>0);}; //指定番号/トラックのCDテキスト文字列の取得 LPCTSTR GetCDTextString(UINT index,UINT uTrack); //指定トラックのアルバム名(曲名)の取得 LPCTSTR GetAlbumName(UINT uTrack){return GetCDTextString(0,uTrack);}; //指定トラックのアーティスト名の取得 LPCTSTR GetArtistName(UINT uTrack){return GetCDTextString(1,uTrack);}; //指定トラックの作曲者名の取得 LPCTSTR GetWriterName(UINT uTrack){return GetCDTextString(3,uTrack);}; //指定トラックのメッセージの取得 LPCTSTR GetMessage(UINT uTrack){return GetCDTextString(5,uTrack);}; //指定トラックのジャンルの取得 LPCTSTR GetGenre(UINT uTrack){return GetCDTextString(7,uTrack);}; //ディスクID情報の取得 LPCTSTR GetDiscID(){return GetCDTextString(6,0);}; //UPC EAN文字列の取得 LPCTSTR GetUPCEAN(UINT uTrack){return GetCDTextString(14,uTrack);}; //サイズ情報の取得 LPCTSTR GetSizeInfo(UINT uTrack){return GetCDTextString(15,uTrack);}; //拡張されたデータの取得 LPCTSTR GetExtData(UINT index); //拡張されたトラックデータの取得 LPCTSTR GetExtTrackData(UINT uTrack); //CDDB(FreeDB)----------------------------- //CDDB(FreeDB)へ問い合わせ // 戻り値://取得した情報の個数 int CDDBQuery(); //CDDB(FreeDB)の読み込み // indexGenre:選択する文字列に対応するリスト(m_strGenre)内の番号 BOOL CDDBRead(int indexGenre); // lpszGenre:ジャンル文字列 // lpszDiscID:ディスクID文字列(16進8桁表記でa~fは小文字) BOOL CDDBRead(LPCTSTR lpszGenre,LPCTSTR lpszDiscID); //CDDB(FreeDB)への問い合わせに必要な情報 CString m_strURL; //問い合わせ先のURL CString m_strUser; //ユーザー名 CString m_strServer; //サーバー名 CString m_strSystem; //システム名 CString m_strVersion; //バージョン名 int m_nProtocol; //プロトコル番号 //CDDB(FreeDB)の問い合わせで得られた文字列 CStringArray m_listGenre;//入手できるジャンルのリスト CString m_strCDDB; //送られてきた文字列 CString m_strYear; //CDのリリース年 CStringArray m_listExtd; //拡張データ CStringArray m_listExtt; //拡張トラックデータ CString m_strPlayOrder;//演奏手順 protected: //指定ファイル名に相当するトラックをオープンします。(オーバーライド) // lpszFileName:ドライブ番号:\Track??.cda(cdaファイルを読み込みます。) // :ドライブ番号:\Track??.cdda(cdaファイルがない) // :上記以外はCWaveFile::ReadFile関数を呼び出します。 virtual BOOL ReadFile(LPCTSTR lpszFileName); //基底クラスに読み込み用のバッファサイズを戻します。 virtual UINT GetSizeOfLoadBuffer(){ return (IsCDDAFile())?RAW_SECTOR_SIZE*8:CWaveOut::GetSizeOfLoadBuffer(); }; //基底クラスに保存バッファサイズを戻します。 virtual UINT GetSizeOfSaveBuffer(){ return (IsCDDAFile())?RAW_SECTOR_SIZE*8:CWaveFile::GetSizeOfSaveBuffer(); }; //CD-DA操作用変数----------------------------- protected: TCHAR m_tchDrive; //CDROMドライブ文字 HANDLE m_hDrive; //CDROMデバイスハンドル CDROM_SESSION m_session; //CDROMセッション情報 CDDA_TOC m_TOC; //CDDA TOC UINT m_sessionCDDA; //CDDAデータのあるセッション番号 CDAFORMAT m_cdafmt; //cdaファイル情報 UINT m_nStartSector; //開始セクタ番号 UINT m_nStopSector; //終了セクタ番号 UINT m_indexSector; //現在のセクタ番号 UINT m_nTotalSector; //現在のトラックのセクタ数 CByteArray m_byteCache; //前回読み込んだデータの残りを一時保存するキャッシュ }; //CDROMのドアを閉める inline BOOL CDDAFile::CloseDoor() { if (m_hDrive==INVALID_HANDLE_VALUE) return FALSE; DWORD BytesReturned=0; return ::DeviceIoControl(m_hDrive,IOCTL_CDROM_LOAD_MEDIA,NULL,0,NULL,0,&BytesReturned,0); } //CDROMのドアを開ける inline BOOL CDDAFile::OpenDoor() { if (m_hDrive==INVALID_HANDLE_VALUE) return FALSE; DWORD BytesReturned=0; return ::DeviceIoControl(m_hDrive,IOCTL_CDROM_EJECT_MEDIA,NULL,0,NULL,0,&BytesReturned,0); } //アクセス可能かどうか inline BOOL CDDAFile::IsReady() { if (m_hDrive==INVALID_HANDLE_VALUE) return FALSE; DWORD BytesReturned=0; return ::DeviceIoControl(m_hDrive,IOCTL_CDROM_CHECK_VERIFY,NULL,0,NULL,0,&BytesReturned,0); } //CDROMを停止する inline BOOL CDDAFile::StopCDDA() { if (m_hDrive==INVALID_HANDLE_VALUE) return FALSE; DWORD BytesReturned=0; return ::DeviceIoControl(m_hDrive,IOCTL_CDROM_STOP_AUDIO,NULL,0,NULL,0,&BytesReturned,0); } //指定番号/トラックのCDテキスト文字列の取得 inline LPCTSTR CDDAFile::GetCDTextString(UINT index,UINT uTrack) { //CDテキストがない場合は、FALSEを返して終了します。 if (!HasCDText()) return FALSE; if ((uTrack>m_TOC.LastTrack)|| ((UINT)m_listCDText[index].GetSize()-1=(UINT)m_listExtd.GetSize())) return FALSE; return m_listExtd[index]; } //拡張されたトラックデータの取得 inline LPCTSTR CDDAFile::GetExtTrackData(UINT uTrack) { if ((!HasCDText())||(uTrack>=(UINT)m_listExtt.GetSize())) return FALSE; return m_listExtt[uTrack]; }