⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wave.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 3 页
字号:
     {
        DriverCallback(pClient->dwCallback, HIWORD(pClient->dwFlags),
                       (HDRVR)pClient->hWave,  DeviceType == WaveOutDevice ? WOM_OPEN : WIM_OPEN, 
                       pClient->dwInstance, 0L, 0L);                 
     }

	return MMSYSERR_NOERROR;
}


//FIXME: MS-specific code, except for name of the func!
MMRESULT GetPositionWaveDevice(PWAVEALLOC pClient, LPMMTIME lpmmt, DWORD dwSize)
{
	/*
    WAVE_DD_POSITION PositionData;
    MMRESULT mErr;

    if (dwSize < sizeof(MMTIME))
        return MMSYSERR_ERROR;

    //
    // Get the current position from the driver
    //
    mErr = sndGetHandleData(pClient->hDev,
                            sizeof(PositionData),
                            &PositionData,
                            IOCTL_WAVE_GET_POSITION,
                            pClient->Event);

    if (mErr == MMSYSERR_NOERROR) {
        if (lpmmt->wType == TIME_BYTES) {
            lpmmt->u.cb = PositionData.ByteCount;
        }

        // default is samples.
        else {
            lpmmt->wType = TIME_SAMPLES;
            lpmmt->u.sample = PositionData.SampleCount;
        }
    }

    return mErr;*/ return MMSYSERR_NOERROR;
}



MMRESULT soundSetData(UINT DeviceType, UINT DeviceId, UINT Length, PBYTE Data,
                     ULONG Ioctl)
{
    HANDLE hDevcie;
    MMRESULT Result;
    DWORD BytesReturned;

    Result = OpenDevice(DeviceType, DeviceId, &hDevcie, GENERIC_READ);
    if (Result != MMSYSERR_NOERROR) 
         return Result;

    Result = DeviceIoControl(hDevcie, Ioctl, Data, Length, NULL, 0, &BytesReturned, NULL) ? 
                             MMSYSERR_NOERROR : TranslateStatus();
    CloseHandle(hDevcie);

	return Result;
}

MMRESULT soundGetData(UINT DeviceType, UINT DeviceId, UINT Length, PBYTE Data,
                     ULONG Ioctl)
{
	HANDLE hDevice;
    MMRESULT Result;
    DWORD BytesReturned;

    Result = OpenDevice(DeviceType, DeviceId, &hDevice, GENERIC_READ);
    if (Result != MMSYSERR_NOERROR)     
         return Result;
        
    Result = DeviceIoControl(hDevice, Ioctl, NULL, 0, (LPVOID)Data, Length,
                           &BytesReturned, NULL) ? MMSYSERR_NOERROR : TranslateStatus();
    CloseHandle(hDevice);
    return Result;
}


/* ============================
 *  EXPORT
 *  functions start here
 * ============================
 */

/*
 * @implemented
 */
APIENTRY DWORD wodMessage(DWORD dwId, DWORD dwMessage, DWORD dwUser, DWORD dwParam1, DWORD dwParam2)
{
    PWAVEALLOC pTask = (PWAVEALLOC)dwUser;

    switch (dwMessage) {
        case WODM_GETNUMDEVS:
            DPRINT("WODM_GETNUMDEVS");
            return GetDeviceCount(WaveOutDevice);

        case WODM_GETDEVCAPS:
            DPRINT("WODM_GETDEVCAPS");
            return GetDeviceCapabilities(dwId, WaveOutDevice, (LPBYTE)dwParam1,
                                  (DWORD)dwParam2);

        case WODM_OPEN:
            DPRINT("WODM_OPEN");
            return OpenWaveDevice(WaveOutDevice, dwId, dwUser, dwParam1, dwParam2);

        case WODM_CLOSE:
			{	
				DPRINT("WODM_CLOSE");

				// 1. Check if the task is ready to complete
                pTask->AuxFunction = WaveThreadClose;
                SetEvent(pTask->AuxEvent1);
                WaitForSingleObject(pTask->AuxEvent2, INFINITE);
	            			
				if ( pTask->AuxReturnCode != MMSYSERR_NOERROR) 
                {
				    return pTask->AuxReturnCode;
				}
				else
					
                {
                    if (pTask->dwCallback)
                    {
                        DriverCallback(pTask->dwCallback, HIWORD(pTask->dwFlags), (HDRVR)pTask->hWave, 
                                       WOM_CLOSE, pTask->dwInstance, 0L, 0L);                   
                    }
                }

				
				// 2. Close the device
				if (pTask->hDev != INVALID_HANDLE_VALUE) {
					CloseHandle(pTask->hDev);

					EnterCriticalSection(&CS);
					pTask->hDev = INVALID_HANDLE_VALUE;
					LeaveCriticalSection(&CS);
				}

				return MMSYSERR_NOERROR;
			};

        case WODM_WRITE:
			{
				LPWAVEHDR pWaveHdr = (LPWAVEHDR)dwParam1;

				DPRINT("WODM_WRITE");

				if (dwParam1 != 0)
					return MMSYSERR_INVALPARAM;

				if ((pWaveHdr->dwFlags & ~(WHDR_INQUEUE|WHDR_DONE|WHDR_PREPARED|WHDR_BEGINLOOP|WHDR_ENDLOOP)))
					return MMSYSERR_INVALPARAM;

				pWaveHdr->dwFlags &= (WHDR_INQUEUE|WHDR_DONE|WHDR_PREPARED|WHDR_BEGINLOOP|WHDR_ENDLOOP);

				if ((pWaveHdr->dwFlags & WHDR_PREPARED) == 0)
					return MMSYSERR_INVALPARAM;

				// Check, if the wave header is already prepared
				if (!(pWaveHdr->dwFlags & WHDR_PREPARED))
					return WAVERR_UNPREPARED;

				// If it's already located in the queue, this op is impossible
				if (pWaveHdr->dwFlags & WHDR_INQUEUE )
					return ( WAVERR_STILLPLAYING );

				// save WAVEALLOC pointer in the WaveHeader
				pWaveHdr->reserved = dwUser;

				
                pWaveHdr->dwFlags |= WHDR_INQUEUE;
                pWaveHdr->dwFlags &= ~WHDR_DONE;
                pTask->AuxParam.pHdr = pWaveHdr;
                
                pTask->AuxFunction = WaveThreadAddBuffer;
                SetEvent(pTask->AuxEvent1);
                WaitForSingleObject(pTask->AuxEvent2, INFINITE);
                return pTask->AuxReturnCode;
			}

        case WODM_PAUSE:
            DPRINT("WODM_PAUSE");
            pTask->AuxParam.State = WAVE_DD_STOP;
           
            pTask->AuxFunction = WaveThreadSetState;
            SetEvent(pTask->AuxEvent1);
            WaitForSingleObject(pTask->AuxEvent2, INFINITE);
	        return pTask->AuxReturnCode;

        case WODM_RESTART:
            DPRINT("WODM_RESTART");
            pTask->AuxParam.State = WAVE_DD_PLAY;

            pTask->AuxFunction = WaveThreadSetState;
            SetEvent(pTask->AuxEvent1);
            WaitForSingleObject(pTask->AuxEvent2, INFINITE);
	        return pTask->AuxReturnCode;            

        case WODM_RESET:
            DPRINT("WODM_RESET");
            pTask->AuxParam.State = WAVE_DD_RESET;

            pTask->AuxFunction = WaveThreadSetState;
            SetEvent(pTask->AuxEvent1);
            WaitForSingleObject(pTask->AuxEvent2, INFINITE);
	        return pTask->AuxReturnCode;
           
        case WODM_BREAKLOOP:
            DPRINT("WODM_BREAKLOOP");

            pTask->AuxFunction = WaveThreadBreakLoop;
            SetEvent(pTask->AuxEvent1);
            WaitForSingleObject(pTask->AuxEvent2, INFINITE);
	        return pTask->AuxReturnCode;

        case WODM_GETPOS:
            DPRINT("WODM_GETPOS");
            return GetPositionWaveDevice(pTask, (LPMMTIME)dwParam1, dwParam2);

        case WODM_SETPITCH:
            DPRINT("WODM_SETPITCH");
            pTask->AuxParam.GetSetData.pData = (PBYTE)&dwParam1;
            pTask->AuxParam.GetSetData.DataLen = sizeof(DWORD);
            pTask->AuxParam.GetSetData.Function = IOCTL_WAVE_SET_PITCH;
            
            pTask->AuxFunction = WaveThreadSetData;
            SetEvent(pTask->AuxEvent1);
            WaitForSingleObject(pTask->AuxEvent2, INFINITE);
	        return pTask->AuxReturnCode;

        case WODM_SETVOLUME:
            DPRINT("WODM_SETVOLUME");
            {
                WAVE_DD_VOLUME Vol;
                Vol.Left = LOWORD(dwParam1) << 16;
                Vol.Right = HIWORD(dwParam1) << 16;

                return soundSetData(WaveOutDevice, dwId, sizeof(Vol),
                                  (PBYTE)&Vol, IOCTL_WAVE_SET_VOLUME);
            }

        case WODM_SETPLAYBACKRATE:
            DPRINT("WODM_SETPLAYBACKRATE");
            pTask->AuxParam.GetSetData.pData = (PBYTE)&dwParam1;
            pTask->AuxParam.GetSetData.DataLen = sizeof(DWORD);
            pTask->AuxParam.GetSetData.Function = IOCTL_WAVE_SET_PLAYBACK_RATE;
            
            pTask->AuxFunction = WaveThreadSetData;
            SetEvent(pTask->AuxEvent1);
            WaitForSingleObject(pTask->AuxEvent2, INFINITE);
	        return pTask->AuxReturnCode;


        case WODM_GETPITCH:
            DPRINT("WODM_GETPITCH");
            pTask->AuxParam.GetSetData.pData = (PBYTE)dwParam1;
            pTask->AuxParam.GetSetData.DataLen = sizeof(DWORD);
            pTask->AuxParam.GetSetData.Function = IOCTL_WAVE_GET_PITCH;
            
            pTask->AuxFunction = WaveThreadGetData;
            SetEvent(pTask->AuxEvent1);
            WaitForSingleObject(pTask->AuxEvent2, INFINITE);
	        return pTask->AuxReturnCode;

        case WODM_GETVOLUME:
            DPRINT("WODM_GETVOLUME");
            {
                WAVE_DD_VOLUME Vol = {};
                DWORD res;

                res = soundGetData(WaveOutDevice, dwId, sizeof(Vol),
                                (PBYTE)&Vol, IOCTL_WAVE_GET_VOLUME);

                if (res == MMSYSERR_NOERROR)
                    *(LPDWORD)dwParam1 = (DWORD)MAKELONG(HIWORD(Vol.Left), HIWORD(Vol.Right));
                
                return res;
            }

        case WODM_GETPLAYBACKRATE:
            DPRINT("WODM_GETPLAYBACKRATE");
            pTask->AuxParam.GetSetData.pData = (PBYTE)dwParam1;
            pTask->AuxParam.GetSetData.DataLen = sizeof(DWORD);
            pTask->AuxParam.GetSetData.Function = IOCTL_WAVE_GET_PLAYBACK_RATE;
                         
            pTask->AuxFunction = WaveThreadGetData;
            SetEvent(pTask->AuxEvent1);
            WaitForSingleObject(pTask->AuxEvent2, INFINITE);
	        return pTask->AuxReturnCode;

        default:
            return MMSYSERR_NOTSUPPORTED;
    }

	// This point of execution should never be reached
    return MMSYSERR_NOTSUPPORTED;
}


/*
 * @implemented
 */
APIENTRY DWORD widMessage(DWORD dwId, DWORD dwMessage, DWORD dwUser, DWORD dwParam1, DWORD dwParam2)
{
    DPRINT("widMessage\n");

    switch (dwMessage) 
    {
        case WIDM_GETNUMDEVS: 
            DPRINT("WIDM_GETNUMDEVS");
            return GetDeviceCount(WaveInDevice);

        case WIDM_GETDEVCAPS:
            DPRINT("WODM_GETDEVCAPS");
            return GetDeviceCapabilities(dwId, WaveInDevice, (LPBYTE)dwParam1, (DWORD)dwParam2);
             
        case WIDM_OPEN:
            DPRINT("WIDM_OPEN");
            return OpenWaveDevice(WaveInDevice, dwId, dwUser, dwParam1, dwParam2);

        case WIDM_CLOSE:
             return MMSYSERR_NOERROR;

        case WIDM_ADDBUFFER:
             return MMSYSERR_NOERROR;

        case WIDM_STOP:
             return MMSYSERR_NOERROR;

        case WIDM_START:
             return MMSYSERR_NOERROR;

        case WIDM_RESET:
             return MMSYSERR_NOERROR;

        case WIDM_GETPOS:
             return MMSYSERR_NOERROR;


        default :
             return MMSYSERR_NOTSUPPORTED;
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -