掲示板システム
ホーム
アクセス解析
カテゴリ
ログアウト
サウンドデコーダーを作りたいのですが・・ (ID:79097)
名前
ホームページ(ブログ、Twitterなど)のURL (省略可)
本文
まず、デコーダという語句を、勝手にレコーダと読み替えて上記書き込みを していました・・・ それと・・・VBで出来ないのか?と言う部分では、可能性を否定するつも りは全くありません。が、機能的に有利なものを使うのが得策だとは考えて おります。 C言語でも、当時は大変でした・・・ とある商品の開発を行った折の完全に動作していたActiveXのC++ソース コードの一部を掲載します。コメントは、依頼元の都合上、大半を削除させ て頂いております。また、このままでは当然、コンパイルし動作させること はできません。が、オーディオ系のAPIの呼び方の順序や関わりが解るとは 思います。 ※ 申し訳ありませんが、録音部分のコールバック関数周辺のみですが、 長文となっております。これから解るように、ここをVBで記述する のは至難の業と言うか、VBでは、解決できないAPIがありますので・・・ BOOL CUtilCtrl::SampWaveIn(long hWnd) { // TODO: ここにディスパッチ ハンドラ コードを追加してください。 WAVEINCAPS wic; UINT nDevId; MMRESULT rc; long lvol , rvol , lSelect , lMute; long ret; lSelect = 1; ret = VolumeFunction( DEST_RECORD , SET_DEVICE_ONOFF , &lvol , &rvol , &lSelect , MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE ); // YAMAHA OPLx3等のカードの場合、CD Audioが、デフォルトで選択された状態でマイク // を選択しても、反映されない場合がある。故に、一旦CD Audio, MIC以外の必ず存在 // するデバイス(LINE等)を選択し、マイクを選択することで問題を回避。 lSelect = 0; ret = VolumeFunction( DEST_RECORD , GET_DEVICE_ONOFF , &lvol , &rvol , &lSelect , MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE ); if ( ret == 0 && lSelect != 1 ){ lSelect = 1; ret = VolumeFunction2( DEST_RECORD , SET_DEVICE_ONOFF , &lvol , &rvol , &lSelect , MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE ); } lMute = 1; VolumeFunction( DEST_PLAY , SET_VOLUME_MUTE_NORMAL , &lvol , &rvol , &lMute , MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE ); hWndOrg = ( HWND )hWnd; UINT nMaxDevice = waveInGetNumDevs(); hwi = NULL; m_lPeakVolume = 0; for ( nDevId = 0 ; nDevId < nMaxDevice ; nDevId++ ){ rc = waveInGetDevCaps( nDevId , &wic , sizeof( wic ) ); if ( rc == MMSYSERR_NOERROR ){ wfx.wFormatTag = WAVE_FORMAT_PCM; wfx.nChannels = WAVE_FORMAT_1M08; wfx.nSamplesPerSec = 11025; wfx.nAvgBytesPerSec = wfx.nSamplesPerSec; wfx.wBitsPerSample = 8; wfx.nBlockAlign = wfx.nChannels * wfx.wBitsPerSample / 8; wfx.cbSize = 0; do { rc = waveInOpen( &hwi , WAVE_MAPPER , &wfx , ( DWORD )( VOID * )waveInProc , ( DWORD )hWnd , CALLBACK_FUNCTION ); if ( rc != MMSYSERR_NOERROR ){ ::Sleep( 100 ); } }while( rc != MMSYSERR_NOERROR ); break; } } if ( hwi == NULL ) return( FALSE ); else { if ( pPlaybackBuffer == NULL ){ m_lPlaybackBufferSize = wfx.nSamplesPerSec * wfx.wBitsPerSample / 8 * 10; // 10秒間の録音サイズ pPlaybackBuffer = ( void * )HeapAlloc( GetProcessHeap() , HEAP_ZERO_MEMORY , m_lPlaybackBufferSize ); if ( pPlaybackBuffer == NULL ){ rc = waveInClose( hwi ); hwi = NULL; return( FALSE ); } else nPlaybackBufferPos = 0; } else nPlaybackBufferPos = 0; } for ( int i = 0 ; i < MIC_BUFF_COUNT ; i++ ){ DWORD AllocSize = wfx.nSamplesPerSec * wfx.wBitsPerSample / 8 / MIC_SAMP_COUNT; whi[ i ] = ( WAVEHDR * )GlobalAlloc( GPTR , sizeof( WAVEHDR ) ); if ( whi[ i ] ){ whi[ i ]->lpData = ( LPSTR )GlobalAlloc( GPTR , AllocSize ); whi[ i ]->dwBufferLength = AllocSize; whi[ i ]->dwBytesRecorded = 0; whi[ i ]->dwUser = 0; whi[ i ]->dwFlags = 0; whi[ i ]->dwLoops = 0; whi[ i ]->lpNext = 0; whi[ i ]->reserved = 0; } } m_lCountIn = 0; for ( i = 0 ; i < MIC_BUFF_COUNT ; i++ ){ rc = waveInPrepareHeader( hwi , whi[ i ] , sizeof( WAVEHDR ) ); if ( rc == MMSYSERR_NOERROR ){ WaitForCallBack( ( long * )&whi[ i ]->dwFlags , WHDR_PREPARED ); rc = waveInAddBuffer( hwi , whi[ i ] , sizeof( WAVEHDR ) ); if ( rc != MMSYSERR_NOERROR ){ break; } else m_lCountIn++; } else break; } if ( rc != MMSYSERR_NOERROR ){ m_lCountIn = 0; StopRecord( ( HWND )hWnd ); return( FALSE ); } for ( i = 0 ; i < MIC_BUFF_COUNT ; i++ ) WaitForCallBack( ( long * )&whi[ i ]->dwFlags , WHDR_PREPARED ); m_fStopIn = FALSE; rc = waveInStart( hwi ); if ( rc != MMSYSERR_NOERROR ){ StopRecord( ( HWND )hWnd ); return( FALSE ); } return TRUE; } void CALLBACK CUtilCtrl::waveInProc(HWAVEIN hwi, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2) { MMRESULT rc; pThisCtl->m_lCountIn--; if ( pThisCtl->m_fStopIn ) return; switch( uMsg ){ case WIM_OPEN: case WIM_CLOSE: break; case WIM_DATA: LPWAVEHDR lpwh = ( LPWAVEHDR )dwParam1; if ( pThisCtl->m_fStartRecord ){ if ( pThisCtl->nPlaybackBufferPos + lpwh->dwBytesRecorded <= pThisCtl->m_lPlaybackBufferSize ){ memcpy( ( ( char * )pThisCtl->pPlaybackBuffer + pThisCtl->nPlaybackBufferPos ) , lpwh->lpData , lpwh->dwBytesRecorded ); pThisCtl->nPlaybackBufferPos += lpwh->dwBytesRecorded; pThisCtl->nPlaybackBufferLen += lpwh->dwBytesRecorded; } else pThisCtl->m_fStartRecord = FALSE; } rc = waveInAddBuffer( pThisCtl->hwi , lpwh , sizeof( WAVEHDR ) ); if (rc != MMSYSERR_NOERROR){ pThisCtl->StopRecord( pThisCtl->hWndOrg ); } else pThisCtl->m_lCountIn++; long lMax = 0; short level = 0; int i; BYTE *pByte; WORD *pWord; switch( pThisCtl->wfx.wBitsPerSample ){ case 8: pByte = ( BYTE * )lpwh->lpData; for ( i = 0 ; i < ( int )( lpwh->dwBytesRecorded ) ; i++ ){ level = ( ( short )*( pByte + i ) ) - 0x007f; if ( lMax < ( long )abs( level ) ) lMax = ( long )abs( level ); } pThisCtl->m_lPeakVolume = ( ( lMax << 8 ) * 100L ) / 0x7fffL; // PeakVolume!! break; case 16: pWord = ( WORD * )lpwh->lpData; for ( i = 0 ; i < ( int )( lpwh->dwBytesRecorded / 2 ) ; i++ ){ level = ( ( short )*( pWord + i ) ) - 0x7fff; if ( lMax < ( long )abs( level ) ) lMax = ( long )abs( level ); } pThisCtl->m_lPeakVolume = ( lMax * 100L ) / 0x7fffL; // PeakVolume!! break; } break; } } int CUtilCtrl::VolumeFunction(int destNo ,int funcNo, long * lvol, long * rvol, long * lmute, long tdwComponentType) { UINT uDest , uConnect , uConnections; MIXERCAPS mxcaps; MIXERLINE mxl; MIXERLINECONTROLS mxlc; PMIXERCONTROL paMixerControls; MIXERCONTROLDETAILS mxcd; MIXERCONTROLDETAILS_UNSIGNED *pmxcdu; MIXERCONTROLDETAILS_BOOLEAN *pmxcdb; MIXERCONTROLDETAILS_LISTTEXT *pmxcdl; long r = 0; int flag; BOOL fDone = FALSE; DWORD dwType0; DWORD dwType1 , dwType2; paMixerControls = NULL; pmxcdu = NULL; pmxcdb = NULL; pmxcdl = NULL; //ミキサーがインストールされているか if ( mixerGetNumDevs() == 0 ){ return( 1 ); } //1つ目のミキサデバイスをオープンする rc = mixerOpen( &hmx , nDevID , 0 , ( DWORD )NULL , MIXER_OBJECTF_MIXER ); if ( rc != MMSYSERR_NOERROR ){ return( 2 ); } //メインのライン出力スピーカを探す mxcaps.cDestinations = 0; mixerGetDevCaps( nDevID , &mxcaps , sizeof( MIXERCAPS ) ); for ( uDest = 0 ; uDest < mxcaps.cDestinations ; uDest++ ){ r = 3; mxl.cbStruct = sizeof( mxl ); mxl.dwDestination = uDest; //ライン情報の取得 rc = mixerGetLineInfo( ( HMIXEROBJ )hmx , &mxl , MIXER_GETLINEINFOF_DESTINATION ); if ( rc != MMSYSERR_NOERROR ){ continue; } switch( funcNo ){ case SET_VOLUME_MAIN: case GET_VOLUME_MAIN: flag = 0; dwType0 = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS; dwType1 = MIXERCONTROL_CONTROLTYPE_VOLUME; dwType2 = -1; break; case SET_VOLUME_MUTE_MAIN: case GET_VOLUME_MUTE_MAIN: flag = 0; dwType0 = tdwComponentType; dwType1 = MIXERCONTROL_CONTROLTYPE_MUTE; dwType2 = MIXERCONTROL_CONTROLF_UNIFORM; break; case SET_VOLUME_NORMAL: case GET_VOLUME_NORMAL: flag = 1; dwType0 = tdwComponentType; dwType1 = MIXERCONTROL_CONTROLTYPE_VOLUME; dwType2 = -1; break; case SET_VOLUME_MUTE_NORMAL: case GET_VOLUME_MUTE_NORMAL: flag = 1; dwType0 = tdwComponentType; dwType1 = MIXERCONTROL_CONTROLTYPE_MUTE; dwType2 = MIXERCONTROL_CONTROLF_UNIFORM; break; case SET_DEVICE_ONOFF: case GET_DEVICE_ONOFF: flag = 2; dwType0 = tdwComponentType; dwType1 = -1; dwType2 = MIXERCONTROL_CONTROLF_UNIFORM; break; } switch( flag ){ case 0: // メインボリューム側処理 if ( uDest == ( UINT )destNo && mxl.dwComponentType == dwType0 ){ r = 0; rc = mixerGetLineInfo( ( HMIXEROBJ )hmx , &mxl , MIXER_GETLINEINFOF_LINEID ); if ( rc != MMSYSERR_NOERROR ){ r = 4; break; } if ( mxl.cControls == 0 ){ r = 5; break; } //PMIXERCONTROL構造体の配列のためのメモリを割り当てる paMixerControls = ( PMIXERCONTROL )GlobalAlloc( GPTR , sizeof( MIXERCONTROL ) * mxl.cControls ); if ( !paMixerControls ){ r = 10; break; } //MIXERLINECONTROLS構造体を設定 mxlc.cbStruct = sizeof( mxlc ); mxlc.dwLineID = mxl.dwLineID; mxlc.dwControlID = 0; mxlc.dwControlType = 0; mxlc.cControls = mxl.cControls; mxlc.cbmxctrl = sizeof( MIXERCONTROL ); mxlc.pamxctrl = paMixerControls; rc = mixerGetLineControls( ( HMIXEROBJ )hmx , &mxlc , MIXER_GETLINECONTROLSF_ALL ); if ( rc != MMSYSERR_NOERROR ){ r = 11; } else { UINT u; for ( u = 0 ; u < mxlc.cControls ; u++ ){ if ( dwType2 == -1 ){ if ( paMixerControls[ u ].dwControlType == dwType1 ){ r = -1; //コントロールがアクティブか確認 if ( paMixerControls[ u ].fdwControl & MIXERCONTROL_CONTROLF_DISABLED ){ r = 13; break; } //pmxcduのメモリ確保 pmxcdu = ( MIXERCONTROLDETAILS_UNSIGNED * )GlobalAlloc( GPTR , mxl.cChannels * sizeof( MIXERCONTROLDETAILS_UNSIGNED ) ); if ( pmxcdu == NULL ){ r = 14; break; } //MIXERCONTROLDETAILS構造体の設定 mxcd.cbStruct = sizeof( MIXERCONTROLDETAILS ); mxcd.dwControlID = paMixerControls[ u ].dwControlID; mxcd.cChannels = mxl.cChannels; mxcd.cMultipleItems = paMixerControls[ u ].cMultipleItems; mxcd.cbDetails = sizeof( MIXERCONTROLDETAILS_UNSIGNED ); mxcd.paDetails = pmxcdu; rc = mixerGetControlDetails( ( HMIXEROBJ )hmx , &mxcd , 0L ); if ( rc != MMSYSERR_NOERROR ){ r = 30; } else { switch( funcNo ){ case SET_VOLUME_MAIN: case SET_VOLUME_NORMAL: //メインボリュームの設定 pmxcdu[ 0 ].dwValue = ( DWORD )*lvol; pmxcdu[ 1 ].dwValue = ( DWORD )*rvol; rc = mixerSetControlDetails( ( HMIXEROBJ )hmx , &mxcd , 0L ); if ( rc != MMSYSERR_NOERROR ){ r = 31; } else fDone = TRUE; break; case GET_VOLUME_MAIN: //メインボリュームの数値 *lvol = pmxcdu[ 0 ].dwValue; *rvol = pmxcdu[ 1 ].dwValue; fDone = TRUE; break; } // HeapFree( GetProcessHeap() , 0 , pmxcdu ); GlobalFree( ( HGLOBAL )pmxcdu ); } break; } } else { if ( ( paMixerControls[ u ].dwControlType == dwType1 ) && ( paMixerControls[ u ].fdwControl & dwType2 ) ){ r = -1; //コントロールがアクティブか確認 if ( paMixerControls[ u ].fdwControl & MIXERCONTROL_CONTROLF_DISABLED ){ r = 13; break; } //pmxcduのメモリ確保 switch( funcNo ){ case SET_VOLUME_MUTE_MAIN: pmxcdb = ( MIXERCONTROLDETAILS_BOOLEAN * )GlobalAlloc( GPTR , mxl.cChannels * sizeof( MIXERCONTROLDETAILS_BOOLEAN ) ); break; case GET_VOLUME_MUTE_MAIN: pmxcdb = ( MIXERCONTROLDETAILS_BOOLEAN * )GlobalAlloc( GPTR , mxl.cChannels * sizeof( MIXERCONTROLDETAILS_BOOLEAN ) ); break; } if ( pmxcdb == NULL ){ r = 14; break; } //MIXERCONTROLDETAILS構造体の設定 mxcd.cbStruct = sizeof( MIXERCONTROLDETAILS ); mxcd.dwControlID = paMixerControls[ u ].dwControlID; mxcd.cChannels = 1; mxcd.cMultipleItems = paMixerControls[ u ].cMultipleItems; mxcd.cbDetails = sizeof( MIXERCONTROLDETAILS_BOOLEAN ); mxcd.paDetails = pmxcdb; rc = mixerGetControlDetails( ( HMIXEROBJ )hmx , &mxcd , 0L ); if ( rc != MMSYSERR_NOERROR ){ r = 30; } else { switch( funcNo ){ case SET_VOLUME_MUTE_MAIN: //メインボリュームの設定 pmxcdb->fValue = *lmute; rc = mixerSetControlDetails( ( HMIXEROBJ )hmx , &mxcd , 0L ); if ( rc != MMSYSERR_NOERROR ){ r = 31; } else fDone = TRUE; break; case GET_VOLUME_MUTE_MAIN: //メインボリュームの数値 *lmute = pmxcdb->fValue; fDone = TRUE; break; } } GlobalFree( ( HGLOBAL )pmxcdb ); break; } } } } GlobalFree( ( HGLOBAL )paMixerControls ); if ( fDone ) break; } break; case 1: // 通常ボリューム側処理 uConnections = ( UINT )mxl.cConnections; for ( uConnect = 0 ; uConnect < uConnections ; uConnect++ ){ mxl.cbStruct = sizeof( mxl ); mxl.dwDestination = uDest; mxl.dwSource = uConnect; rc = mixerGetLineInfo( ( HMIXEROBJ )hmx , &mxl , MIXER_GETLINEINFOF_SOURCE ); if ( rc != MMSYSERR_NOERROR ){ r = 40; break; } if ( uDest == ( UINT )destNo && mxl.dwComponentType == ( DWORD )tdwComponentType ){ r = 0; rc = mixerGetLineInfo( ( HMIXEROBJ )hmx , &mxl , MIXER_GETLINEINFOF_LINEID ); if ( rc != MMSYSERR_NOERROR ){ r = 4; break; } if ( mxl.cControls == 0 ){ r = 5; break; } //PMIXERCONTROL構造体の配列のためのメモリを割り当てる paMixerControls = ( PMIXERCONTROL )GlobalAlloc( GPTR , sizeof( MIXERCONTROL ) * mxl.cControls ); if ( !paMixerControls ){ r = 10; break; } //MIXERLINECONTROLS構造体を設定 mxlc.cbStruct = sizeof( mxlc ); mxlc.dwLineID = mxl.dwLineID; mxlc.dwControlID = 0; mxlc.dwControlType = 0; mxlc.cControls = mxl.cControls; mxlc.cbmxctrl = sizeof( MIXERCONTROL ); mxlc.pamxctrl = paMixerControls; rc = mixerGetLineControls( ( HMIXEROBJ )hmx , &mxlc , MIXER_GETLINECONTROLSF_ALL ); if ( rc != MMSYSERR_NOERROR ){ r = 11; } else { UINT u; for ( u = 0 ; u < mxlc.cControls ; u++ ){ if ( dwType2 == -1 ){ if ( paMixerControls[ u ].dwControlType == dwType1 ){ r = -1; //正しいコントロールかどうか確認 if ( !( paMixerControls[ u ].dwControlType & dwType1 ) ){ r = 12; break; } //コントロールがアクティブか確認 if ( paMixerControls[ u ].fdwControl & MIXERCONTROL_CONTROLF_DISABLED ){ r = 13; break; } //pmxcduのメモリ確保 pmxcdu = ( MIXERCONTROLDETAILS_UNSIGNED * )GlobalAlloc( GPTR , mxl.cChannels * sizeof( MIXERCONTROLDETAILS_UNSIGNED ) ); //MIXERCONTROLDETAILS構造体の設定 mxcd.cbStruct = sizeof( MIXERCONTROLDETAILS ); mxcd.dwControlID = paMixerControls[ u ].dwControlID; mxcd.cChannels = mxl.cChannels; mxcd.cMultipleItems = paMixerControls[ u ].cMultipleItems; mxcd.cbDetails = sizeof( MIXERCONTROLDETAILS_UNSIGNED ); mxcd.paDetails = pmxcdu; rc = mixerGetControlDetails( ( HMIXEROBJ )hmx , &mxcd , 0L ); if ( rc != MMSYSERR_NOERROR ){ r = 30; } else { switch( funcNo ){ case SET_VOLUME_NORMAL: //メインボリュームの設定 pmxcdu[ 0 ].dwValue = ( DWORD )*lvol; pmxcdu[ 1 ].dwValue = ( DWORD )*rvol; rc = mixerSetControlDetails( ( HMIXEROBJ )hmx , &mxcd , 0L ); if ( rc != MMSYSERR_NOERROR ){ r = 31; } else fDone = TRUE; break; case GET_VOLUME_NORMAL: //メインボリュームの数値 *lvol = pmxcdu[ 0 ].dwValue; *rvol = pmxcdu[ 1 ].dwValue; fDone = TRUE; break; } } GlobalFree( ( HGLOBAL )pmxcdu ); break; } } else { if ( ( paMixerControls[ u ].dwControlType == dwType1 ) && ( paMixerControls[ u ].fdwControl & dwType2 ) ){ r = -1; //正しいコントロールかどうか確認 if ( !( paMixerControls[ u ].dwControlType & dwType1 ) ){ r = 12; break; } //コントロールがアクティブか確認 if ( paMixerControls[ u ].fdwControl & MIXERCONTROL_CONTROLF_DISABLED ){ r = 13; break; } //pmxcduのメモリ確保 pmxcdb = ( MIXERCONTROLDETAILS_BOOLEAN * )GlobalAlloc( GPTR , mxl.cChannels * sizeof( MIXERCONTROLDETAILS_BOOLEAN ) ); if ( pmxcdb == NULL ){ r = 14; break; } //MIXERCONTROLDETAILS構造体の設定 mxcd.cbStruct = sizeof( MIXERCONTROLDETAILS ); mxcd.dwControlID = paMixerControls[ u ].dwControlID; mxcd.cChannels = 1; mxcd.cMultipleItems = paMixerControls[ u ].cMultipleItems; mxcd.cbDetails = sizeof( MIXERCONTROLDETAILS_BOOLEAN ); mxcd.paDetails = pmxcdb; rc = mixerGetControlDetails( ( HMIXEROBJ )hmx , &mxcd , 0L ); if ( rc != MMSYSERR_NOERROR ){ r = 30; } else { switch( funcNo ){ case SET_VOLUME_MUTE_NORMAL: //メインボリュームの設定 pmxcdb->fValue = ( DWORD )*lmute; rc = mixerSetControlDetails( ( HMIXEROBJ )hmx , &mxcd , MIXER_SETCONTROLDETAILSF_VALUE ); if ( rc != MMSYSERR_NOERROR ){ r = 31; } else fDone = TRUE; break; case GET_VOLUME_MUTE_NORMAL: //メインボリュームの数値 *lmute = pmxcdb->fValue; fDone = TRUE; break; } } GlobalFree( ( HGLOBAL )pmxcdb ); break; } } } } GlobalFree( ( HGLOBAL )paMixerControls ); if ( fDone ) break; } } break; case 2: r = 4; if ( uDest != ( UINT )destNo ) break; UINT u , uMaxConnections; int Index = -1 , j; uMaxConnections = mxl.cConnections; rc = mixerGetLineInfo( ( HMIXEROBJ )hmx , &mxl , MIXER_GETLINEINFOF_LINEID ); if ( rc != MMSYSERR_NOERROR ){ r = 4; break; } if ( mxl.cControls == 0 ){ r = 5; break; } paMixerControls = ( PMIXERCONTROL )GlobalAlloc( GPTR , sizeof( MIXERCONTROL ) * mxl.cControls ); if ( !paMixerControls ){ r = 10; break; } //MIXERLINECONTROLS構造体を設定 mxlc.cbStruct = sizeof( mxlc ); mxlc.dwLineID = mxl.dwLineID; mxlc.dwControlID = 0; mxlc.dwControlType = 0; mxlc.cControls = mxl.cControls; mxlc.cbmxctrl = sizeof( MIXERCONTROL ); mxlc.pamxctrl = paMixerControls; rc = mixerGetLineControls( ( HMIXEROBJ )hmx , &mxlc , MIXER_GETLINECONTROLSF_ALL ); if ( rc == MMSYSERR_NOERROR ){ for ( u = 0 ; u < mxlc.cControls ; u++ ){ if ( ( ( paMixerControls[ u ].dwControlType == MIXERCONTROL_CONTROLTYPE_MUX ) || ( paMixerControls[ u ].dwControlType == MIXERCONTROL_CONTROLTYPE_MIXER ) ) && ( paMixerControls[ u ].fdwControl & dwType2 ) ){ pmxcdl = ( MIXERCONTROLDETAILS_LISTTEXT * )GlobalAlloc( GPTR , paMixerControls[ u ].cMultipleItems * sizeof( MIXERCONTROLDETAILS_LISTTEXT ) ); //MIXERCONTROLDETAILS構造体の設定 mxcd.cbStruct = sizeof( MIXERCONTROLDETAILS ); mxcd.dwControlID = 0; mxcd.cChannels = 1; mxcd.cMultipleItems = paMixerControls[ u ].cMultipleItems; mxcd.cbDetails = sizeof( MIXERCONTROLDETAILS_LISTTEXT ); mxcd.paDetails = pmxcdl; rc = mixerGetControlDetails( ( HMIXEROBJ )hmx , &mxcd , MIXER_GETCONTROLDETAILSF_LISTTEXT ); if ( rc == MMSYSERR_NOERROR ){ for ( j = 0 ; j < ( int )paMixerControls[ u ].cMultipleItems ; j++ ){ if ( pmxcdl[ j ].dwParam2 == ( DWORD )dwType0 ){ Index = ( int )j; break; } } } GlobalFree( ( HGLOBAL )pmxcdl ); } if ( Index != -1 ) break; } } GlobalFree( ( HGLOBAL )paMixerControls ); if ( Index != -1 ){ //pmxcduのメモリ確保 pmxcdb = ( MIXERCONTROLDETAILS_BOOLEAN * )GlobalAlloc( GPTR , uMaxConnections * sizeof( MIXERCONTROLDETAILS_BOOLEAN ) ); if ( pmxcdb ){ //MIXERCONTROLDETAILS構造体の設定 mxcd.cbStruct = sizeof( MIXERCONTROLDETAILS ); mxcd.dwControlID = 0; mxcd.cChannels = 1; mxcd.cMultipleItems = uMaxConnections; mxcd.cbDetails = sizeof( MIXERCONTROLDETAILS_BOOLEAN ); mxcd.paDetails = pmxcdb; rc = mixerGetControlDetails( ( HMIXEROBJ )hmx , &mxcd , MIXER_GETCONTROLDETAILSF_VALUE ); if ( rc == MMSYSERR_NOERROR ){ switch( funcNo ){ case SET_DEVICE_ONOFF: //メインボリュームの設定 pmxcdb[ Index ].fValue = ( DWORD )*lmute; rc = mixerSetControlDetails( ( HMIXEROBJ )hmx , &mxcd , MIXER_SETCONTROLDETAILSF_VALUE ); if ( rc != MMSYSERR_NOERROR ){ r = 31; } else fDone = TRUE; break; case GET_DEVICE_ONOFF: //メインボリュームの数値 *lmute = pmxcdb[ Index ].fValue; fDone = TRUE; break; } } GlobalFree( ( HGLOBAL )pmxcdb ); } } break; } if ( fDone ){ r = 0; break; } } rc = mixerClose( hmx ); return( r ); } 以上。
←解決時は質問者本人がここをチェックしてください。
戻る
掲示板システム
Copyright 2020 Takeshi Okamoto All Rights Reserved.