CPI_Player.c
上传用户:tuheem
上传日期:2007-05-01
资源大小:21889k
文件大小:13k
- #include "stdafx.h"
- #include "globals.h"
- #include "CPI_Player.h"
- #include "CPI_Player_Messages.h"
- CPI_Player__SetInternalVolume(CPs_PlayEngine* pPlayEngine, const int iNewVolume);
- CP_HPLAYER CPI_Player__Create(HWND hWndMain)
- {
- CPs_PlayEngine* pNewPlayEngine;
- // 线程控制对象
- pNewPlayEngine = (CPs_PlayEngine*)malloc(sizeof(CPs_PlayEngine));
- pNewPlayEngine->m_hWndNotify = hWndMain;
- // 创建事件,当线程准备好输入时,事件将被通知
- pNewPlayEngine->m_hEvtThreadReady = CreateEvent(NULL, FALSE, FALSE, NULL);
- // 创建线程
- pNewPlayEngine->m_hThread = CreateThread(NULL, 0, CPI_Player__EngineEP, pNewPlayEngine, 0, &(pNewPlayEngine->m_dwThreadID) );
- CP_ASSERT(pNewPlayEngine->m_hThread);
- // 等待引擎就绪
- WaitForSingleObject(pNewPlayEngine->m_hEvtThreadReady, INFINITE);
- CloseHandle(pNewPlayEngine->m_hEvtThreadReady);
- pNewPlayEngine->m_hEvtThreadReady = NULL;
- pNewPlayEngine->m_hVolumeMixer = NULL;
- CPI_Player__ReopenMixer((CP_HPLAYER)pNewPlayEngine);
- return (CP_HPLAYER)pNewPlayEngine;
- }
- //
- //
- //
- void CPI_Player__Destroy(CP_HPLAYER hPlayer)
- {
- CPs_PlayEngine* pPlayEngine = (CPs_PlayEngine*)hPlayer;
- CP_CHECKOBJECT(pPlayEngine);
- // 请求线程关闭
- PostThreadMessage(pPlayEngine->m_dwThreadID, CPTM_STOP, 0, 0);
- PostThreadMessage(pPlayEngine->m_dwThreadID, CPTM_QUIT, 0, 0);
- // 关闭音量混合器
- if(pPlayEngine->m_hVolumeMixer)
- mixerClose(pPlayEngine->m_hVolumeMixer);
- // 等待关闭实际上发生
- WaitForSingleObject(pPlayEngine->m_hThread, INFINITE);
- // 清空
- CloseHandle(pPlayEngine->m_hThread);
- free(pPlayEngine);
- }
- //
- //
- //
- void CPI_Player__ReopenMixer(CP_HPLAYER hPlayer)
- {
- CPs_PlayEngine* pPlayEngine = (CPs_PlayEngine*)hPlayer;
- WAVEFORMATEX waveformatex;
- HWAVEOUT hWaveOut;
- CP_CHECKOBJECT(pPlayEngine);
- // 关闭音量混合器
- if(pPlayEngine->m_hVolumeMixer)
- {
- mixerClose(pPlayEngine->m_hVolumeMixer);
- pPlayEngine->m_hVolumeMixer = NULL;
- }
- if(globals.m_enMixerMode == mmMasterVolume || globals.m_enMixerMode == mmWaveVolume)
- {
- // 通过打开波形输出流并由此打开混声器,获得混声器ID
- waveformatex.wFormatTag = WAVE_FORMAT_PCM;
- waveformatex.nChannels = 2;
- waveformatex.nSamplesPerSec = 44100;
- waveformatex.wBitsPerSample = 16;
- waveformatex.nBlockAlign = (waveformatex.nChannels * waveformatex.wBitsPerSample)>>3;
- waveformatex.nAvgBytesPerSec = waveformatex.nSamplesPerSec * waveformatex.nBlockAlign;
- waveformatex.cbSize = 0;
- waveOutOpen( &hWaveOut,
- WAVE_MAPPER,
- &waveformatex,
- 0,
- 0, CALLBACK_NULL);
- // 为音量创建一个混声器(mixer)控制 (如果可以)
- if(mixerOpen(&pPlayEngine->m_hVolumeMixer, (UINT)hWaveOut, (DWORD)pPlayEngine->m_hWndNotify, 0, CALLBACK_WINDOW | MIXER_OBJECTF_HWAVEOUT) == MMSYSERR_NOERROR)
- {
- MIXERCAPS mixercaps;
- DWORD dwLineID;
- DWORD dwNumControls;
- MIXERLINECONTROLS linecontrols;
- MIXERCONTROL mixercontrol;
- // 为第一个波形输出设备的扬声器获得目的文件的
- mixerGetDevCaps((UINT)pPlayEngine->m_hVolumeMixer, &mixercaps, sizeof(mixercaps));
- {
- MIXERLINE mixerline;
- memset(&mixerline, 0, sizeof(mixerline));
- mixerline.cbStruct = sizeof(mixerline);
- if(globals.m_enMixerMode == mmMasterVolume)
- {
- mixerline.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
- mixerGetLineInfo((HMIXEROBJ)pPlayEngine->m_hVolumeMixer,
- &mixerline,
- MIXER_OBJECTF_HMIXER | MIXER_GETLINEINFOF_COMPONENTTYPE);
- }
- else
- {
- mixerline.Target.dwType = MIXERLINE_TARGETTYPE_WAVEOUT;
- mixerline.Target.wMid = mixercaps.wMid;
- mixerline.Target.wPid = mixercaps.wPid;
- mixerline.Target.vDriverVersion = mixercaps.vDriverVersion;
- strncpy(mixerline.Target.szPname, mixercaps.szPname, sizeof(mixerline.Target.szPname));
- mixerGetLineInfo((HMIXEROBJ)pPlayEngine->m_hVolumeMixer,
- &mixerline,
- MIXER_OBJECTF_HMIXER | MIXER_GETLINEINFOF_TARGETTYPE);
- }
- dwLineID = mixerline.dwLineID;
- dwNumControls = mixerline.cControls;
- }
- // 获得音量控制器的 controlID
- memset(&linecontrols, 0, sizeof(linecontrols));
- linecontrols.cbStruct = sizeof(linecontrols);
- linecontrols.dwLineID = dwLineID;
- linecontrols.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
- linecontrols.cControls = 1;
- linecontrols.cbmxctrl = sizeof(MIXERCONTROL);
- linecontrols.pamxctrl = &mixercontrol;
- memset(&mixercontrol, 0, sizeof(mixercontrol));
- mixercontrol.cbStruct = sizeof(mixercontrol);
- mixerGetLineControls((HMIXEROBJ)pPlayEngine->m_hVolumeMixer,
- &linecontrols,
- MIXER_OBJECTF_HMIXER | MIXER_GETLINECONTROLSF_ONEBYTYPE);
- pPlayEngine->m_dwMixerControlID = mixercontrol.dwControlID;
- CPI_Player__SetInternalVolume(pPlayEngine, 100);
- }
- else
- {
- CP_TRACE0("Failed to open mixer");
- pPlayEngine->m_hVolumeMixer = NULL;
- }
- waveOutClose(hWaveOut);
- }
- else
- {
- CPI_Player__SetInternalVolume(pPlayEngine, globals.m_iVolume);
- }
- }
- //
- //
- //
- void CPI_Player__OpenFile(CP_HPLAYER hPlayer, const char* pcFilename)
- {
- char* pcStringCopy;
- CPs_PlayEngine* pPlayEngine = (CPs_PlayEngine*)hPlayer;
- CP_CHECKOBJECT(pPlayEngine);
- // 对流数据作备份
- STR_AllocSetString(&pcStringCopy, pcFilename, FALSE);
- // 发送消息 (被调用者将释放串)
- PostThreadMessage(pPlayEngine->m_dwThreadID, CPTM_OPENFILE, (WPARAM)pcStringCopy, 0);
- }
- //
- //
- //
- void CPI_Player__Seek(CP_HPLAYER hPlayer, const int iSeekPercent_Numerator, const int iSeekPercent_Denominator)
- {
- CPs_PlayEngine* pPlayEngine = (CPs_PlayEngine*)hPlayer;
- CP_CHECKOBJECT(pPlayEngine);
- // 发送消息
- PostThreadMessage(pPlayEngine->m_dwThreadID, CPTM_SEEK, (WPARAM)iSeekPercent_Numerator, (LPARAM)iSeekPercent_Denominator);
- }
- //
- //
- //
- void CPI_Player__Play(CP_HPLAYER hPlayer)
- {
- CPs_PlayEngine* pPlayEngine = (CPs_PlayEngine*)hPlayer;
- CP_CHECKOBJECT(pPlayEngine);
- // 发送消息
- PostThreadMessage(pPlayEngine->m_dwThreadID, CPTM_PLAY, 0, 0);
- }
- //
- //
- //
- void CPI_Player__Stop(CP_HPLAYER hPlayer)
- {
- CPs_PlayEngine* pPlayEngine = (CPs_PlayEngine*)hPlayer;
- CP_CHECKOBJECT(pPlayEngine);
- // 发送消息
- PostThreadMessage(pPlayEngine->m_dwThreadID, CPTM_STOP, 0, 0);
- }
- //
- //
- //
- void CPI_Player__Pause(CP_HPLAYER hPlayer)
- {
- CPs_PlayEngine* pPlayEngine = (CPs_PlayEngine*)hPlayer;
- CP_CHECKOBJECT(pPlayEngine);
- // 发送消息
- PostThreadMessage(pPlayEngine->m_dwThreadID, CPTM_PAUSE, 0, 0);
- }
- //
- //
- //
- void CPI_Player__BlockMessagesUntilEndOfStream(CP_HPLAYER hPlayer)
- {
- CPs_PlayEngine* pPlayEngine = (CPs_PlayEngine*)hPlayer;
- CP_CHECKOBJECT(pPlayEngine);
- // 发送消息
- PostThreadMessage(pPlayEngine->m_dwThreadID, CPTM_BLOCKMSGUNTILENDOFSTREAM, 0, 0);
- }
- //
- //
- //
- void CPI_Player__SetVolume(CP_HPLAYER hPlayer, const int iNewVolume)
- {
- CPs_PlayEngine* pPlayEngine = (CPs_PlayEngine*)hPlayer;
- CP_CHECKOBJECT(pPlayEngine);
- // 通过混声器设置音量
- if(pPlayEngine->m_hVolumeMixer)
- {
- MIXERCONTROLDETAILS_UNSIGNED VolumeLevel;
- MIXERCONTROLDETAILS details;
- details.cbStruct = sizeof(details);
- details.dwControlID = pPlayEngine->m_dwMixerControlID;
- details.cChannels = 1;
- details.hwndOwner = NULL;
- details.cMultipleItems = 0;
- details.cbDetails = sizeof(VolumeLevel);
- details.paDetails = &VolumeLevel;
- VolumeLevel.dwValue = iNewVolume * 0x28F;
- mixerSetControlDetails((HMIXEROBJ)pPlayEngine->m_hVolumeMixer, &details, MIXER_OBJECTF_HMIXER);
- }
- else
- CPI_Player__SetInternalVolume(pPlayEngine, globals.m_iVolume);
- }
- //
- //
- //
- int CPI_Player__GetVolume(CP_HPLAYER hPlayer)
- {
- CPs_PlayEngine* pPlayEngine = (CPs_PlayEngine*)hPlayer;
- CP_CHECKOBJECT(pPlayEngine);
- // 通过混声器得到音量
- if(pPlayEngine->m_hVolumeMixer)
- {
- MIXERCONTROLDETAILS_UNSIGNED VolumeLevel;
- MIXERCONTROLDETAILS details;
- details.cbStruct = sizeof(details);
- details.dwControlID = pPlayEngine->m_dwMixerControlID;
- details.cChannels = 1;
- details.hwndOwner = NULL;
- details.cMultipleItems = 0;
- details.cbDetails = sizeof(VolumeLevel);
- details.paDetails = &VolumeLevel;
- VolumeLevel.dwValue = 0;
- mixerGetControlDetails((HMIXEROBJ)pPlayEngine->m_hVolumeMixer, &details, MIXER_OBJECTF_HMIXER);
- return VolumeLevel.dwValue / 0x28F;
- }
- else
- return globals.m_iVolume;
- }
- //
- //
- //
- void CPI_Player__SetEQ(CP_HPLAYER hPlayer, const BOOL bEnabled, const int cBands[9])
- {
- int iEQBandIDX;
- CPs_EQSettings* pNewEQSettings;
- CPs_PlayEngine* pPlayEngine = (CPs_PlayEngine*)hPlayer;
- CP_CHECKOBJECT(pPlayEngine);
- // 设置params
- pNewEQSettings = (CPs_EQSettings*)malloc(sizeof(*pNewEQSettings));
- pNewEQSettings->m_bEnabled = bEnabled;
- // 设置带 - 由于一些原因,UI 基于1 !!!
- for(iEQBandIDX = 0; iEQBandIDX < 8; iEQBandIDX++)
- pNewEQSettings->m_aryBands[iEQBandIDX] = (char)cBands[iEQBandIDX+1];
- PostThreadMessage(pPlayEngine->m_dwThreadID, CPTM_SETEQSETTINGS, (WPARAM)pNewEQSettings, 0);
- }
- //
- //
- //
- void CPI_Player__EnumOutputDevices(CP_HPLAYER hPlayer)
- {
- CPs_PlayEngine* pPlayEngine = (CPs_PlayEngine*)hPlayer;
- CP_CHECKOBJECT(pPlayEngine);
- // 发送消息
- PostThreadMessage(pPlayEngine->m_dwThreadID, CPTM_ENUMOUTPUTDEVICES, 0, 0);
- }
- //
- //
- //
- void CPI_Player__SendSyncCookie(CP_HPLAYER hPlayer, const int iCookie)
- {
- CPs_PlayEngine* pPlayEngine = (CPs_PlayEngine*)hPlayer;
- CP_CHECKOBJECT(pPlayEngine);
- // 发送消息
- PostThreadMessage(pPlayEngine->m_dwThreadID, CPTM_SENDSYNCCOOKIE, (WPARAM)iCookie, 0);
- }
- //
- //
- //
- void CPI_Player__SetPositionRange(CP_HPLAYER hPlayer, const int iRange)
- {
- CPs_PlayEngine* pPlayEngine = (CPs_PlayEngine*)hPlayer;
- CP_CHECKOBJECT(pPlayEngine);
- // 发送消息
- PostThreadMessage(pPlayEngine->m_dwThreadID, CPTM_SETPROGRESSTRACKLENGTH, (WPARAM)iRange, 0);
- }
- //
- //
- //
- void CPI_Player__AssociateFileExtensions(CP_HPLAYER hPlayer)
- {
- CPs_PlayEngine* pPlayEngine = (CPs_PlayEngine*)hPlayer;
- CP_CHECKOBJECT(pPlayEngine);
- // 发送消息
- PostThreadMessage(pPlayEngine->m_dwThreadID, CPTM_ASSOCIATEFILEEXTENSIONS, 0, 0);
- }
- //
- //
- //
- BOOL CPI_Player__HandleNotifyMessages(CP_HPLAYER hPlayer, UINT uiMessage, WPARAM wParam, LPARAM lParam, LRESULT* plResult)
- {
- // 如果不是为此目的的消息,则忽略之
- if( (uiMessage < CPNM_first || uiMessage > CPNM_last)
- && uiMessage != MM_MIXM_CONTROL_CHANGE)
- {
- return FALSE;
- }
- // 解码消息
- switch(uiMessage)
- {
- case CPNM_PLAYERSTATE:
- {
- CPe_PlayerState enNewState = (CPe_PlayerState)wParam;
- CPI_Player_cb_OnPlayerState(hPlayer, enNewState);
- }
- break;
- case CPNM_FILEINFO:
- {
- CPs_FileInfo* pFileInfo = (CPs_FileInfo*)wParam;
- CPI_Player_cb_OnStreamInfo(hPlayer, pFileInfo);
- free(pFileInfo);
- }
- break;
- case CPNM_FILEOFFSET_SECS:
- CPI_Player_cb_OnStreamOffset_Secs(hPlayer, (int)wParam);
- break;
- case CPNM_FILEOFFSET_PROP:
- CPI_Player_cb_OnStreamOffset_Range(hPlayer, (int)wParam);
- break;
- case CPNM_SYNCCOOKIE:
- CPI_Player_cb_OnSyncCookie(hPlayer, (int)wParam);
- break;
- case CPNM_FOUNDOUTPUTDEVICE:
- {
- char* pcDeviceName = (char*)wParam;
- CPI_Player_cb_OnEnumOutputDevice(hPlayer, pcDeviceName, (int)lParam);
- if(pcDeviceName)free(pcDeviceName);
- }
- break;
- case CPNM_SETSTREAMINGSTATE:
- CPI_Player_cb_OnStreamStateChange(hPlayer, (BOOL)wParam, (int)lParam);
- break;
- case MM_MIXM_CONTROL_CHANGE:
- {
- const DWORD dwControlID = (DWORD)lParam;
- CPs_PlayEngine* pPlayEngine = (CPs_PlayEngine*)hPlayer;
- CP_CHECKOBJECT(pPlayEngine);
- if(pPlayEngine->m_dwMixerControlID == dwControlID)
- CPI_Player_cb_OnVolumeChange(hPlayer, CPI_Player__GetVolume(hPlayer));
- }
- break;
- }
- return TRUE;
- }
- //
- //
- //
- void CPI_Player__OnOutputDeviceChange(CP_HPLAYER hPlayer)
- {
- CPs_PlayEngine* pPlayEngine = (CPs_PlayEngine*)hPlayer;
- CP_CHECKOBJECT(pPlayEngine);
- // 发送消息
- PostThreadMessage(pPlayEngine->m_dwThreadID, CPTM_ONOUTPUTMODULECHANGE, 0, 0);
- }
- //
- //
- //
- CPI_Player__SetInternalVolume(CPs_PlayEngine* pPlayEngine, const int iNewVolume)
- {
- // 发送消息
- PostThreadMessage(pPlayEngine->m_dwThreadID, CPTM_SETINTERNALVOLUME, (WPARAM)iNewVolume, 0);
- }
- //
- //
- //