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

📄 ao_dsound.c

📁 自己移植的linux下的流媒体播放器原代码,支持mms协议,支持ftp和http协议.
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************** * ao_dsound.c: Windows DirectSound interface for MPlayer * Copyright (c) 2004 Gabor Szecsi <deje@miki.hu> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. * *****************************************************************************//**\todo verify/extend multichannel support*/#include <stdio.h>#include <stdlib.h>#include <windows.h>#define DIRECTSOUND_VERSION 0x0600#include <dsound.h>#include "config.h"#include "libaf/af_format.h"#include "audio_out.h"#include "audio_out_internal.h"#include "mp_msg.h"#include "libvo/fastmemcpy.h"#include "osdep/timer.h"#include "subopt-helper.h"static ao_info_t info ={	"Windows DirectSound audio output",	"dsound",	"Gabor Szecsi <deje@miki.hu>",	""};LIBAO_EXTERN(dsound)/**\todo use the definitions from the win32 api headers when they define these*/#if 1#define WAVE_FORMAT_IEEE_FLOAT 0x0003#define WAVE_FORMAT_DOLBY_AC3_SPDIF 0x0092#define WAVE_FORMAT_EXTENSIBLE 0xFFFEstatic const GUID KSDATAFORMAT_SUBTYPE_PCM = {0x1,0x0000,0x0010, {0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71}};#define SPEAKER_FRONT_LEFT             0x1#define SPEAKER_FRONT_RIGHT            0x2#define SPEAKER_FRONT_CENTER           0x4#define SPEAKER_LOW_FREQUENCY          0x8#define SPEAKER_BACK_LEFT              0x10#define SPEAKER_BACK_RIGHT             0x20#define SPEAKER_FRONT_LEFT_OF_CENTER   0x40#define SPEAKER_FRONT_RIGHT_OF_CENTER  0x80#define SPEAKER_BACK_CENTER            0x100#define SPEAKER_SIDE_LEFT              0x200#define SPEAKER_SIDE_RIGHT             0x400#define SPEAKER_TOP_CENTER             0x800#define SPEAKER_TOP_FRONT_LEFT         0x1000#define SPEAKER_TOP_FRONT_CENTER       0x2000#define SPEAKER_TOP_FRONT_RIGHT        0x4000#define SPEAKER_TOP_BACK_LEFT          0x8000#define SPEAKER_TOP_BACK_CENTER        0x10000#define SPEAKER_TOP_BACK_RIGHT         0x20000#define SPEAKER_RESERVED               0x80000000#define DSSPEAKER_HEADPHONE         0x00000001#define DSSPEAKER_MONO              0x00000002#define DSSPEAKER_QUAD              0x00000003#define DSSPEAKER_STEREO            0x00000004#define DSSPEAKER_SURROUND          0x00000005#define DSSPEAKER_5POINT1           0x00000006#ifndef _WAVEFORMATEXTENSIBLE_typedef struct {    WAVEFORMATEX    Format;    union {        WORD wValidBitsPerSample;       /* bits of precision  */        WORD wSamplesPerBlock;          /* valid if wBitsPerSample==0 */        WORD wReserved;                 /* If neither applies, set to zero. */    } Samples;    DWORD           dwChannelMask;      /* which channels are */                                        /* present in stream  */    GUID            SubFormat;} WAVEFORMATEXTENSIBLE, *PWAVEFORMATEXTENSIBLE;#endif#endifstatic const int channel_mask[] = {  SPEAKER_FRONT_LEFT   | SPEAKER_FRONT_RIGHT  | SPEAKER_LOW_FREQUENCY,  SPEAKER_FRONT_LEFT   | SPEAKER_FRONT_RIGHT  | SPEAKER_BACK_LEFT    | SPEAKER_BACK_RIGHT,  SPEAKER_FRONT_LEFT   | SPEAKER_FRONT_RIGHT  | SPEAKER_BACK_LEFT    | SPEAKER_BACK_RIGHT   | SPEAKER_LOW_FREQUENCY,  SPEAKER_FRONT_LEFT   | SPEAKER_FRONT_CENTER | SPEAKER_FRONT_RIGHT  | SPEAKER_BACK_LEFT    | SPEAKER_BACK_RIGHT     | SPEAKER_LOW_FREQUENCY};static HINSTANCE hdsound_dll = NULL;      ///handle to the dllstatic LPDIRECTSOUND hds = NULL;          ///direct sound object static LPDIRECTSOUNDBUFFER hdspribuf = NULL; ///primary direct sound bufferstatic LPDIRECTSOUNDBUFFER hdsbuf = NULL; ///secondary direct sound buffer (stream buffer)static int buffer_size = 0;               ///size in bytes of the direct sound buffer   static int write_offset = 0;              ///offset of the write cursor in the direct sound bufferstatic int min_free_space = 0;            ///if the free space is below this value get_space() will return 0                                          ///there will always be at least this amout of free space to prevent                                          ///get_space() from returning wrong values when buffer is 100% full.                                          ///will be replaced with nBlockAlign in init()static int device_num = 0;                ///wanted device numberstatic GUID device;                       ///guid of the device /***************************************************************************************//**\brief output error message\param err error code\return string with the error message*/static char * dserr2str(int err){	switch (err) {		case DS_OK: return "DS_OK";		case DS_NO_VIRTUALIZATION: return "DS_NO_VIRTUALIZATION";		case DSERR_ALLOCATED: return "DS_NO_VIRTUALIZATION";		case DSERR_CONTROLUNAVAIL: return "DSERR_CONTROLUNAVAIL";		case DSERR_INVALIDPARAM: return "DSERR_INVALIDPARAM";		case DSERR_INVALIDCALL: return "DSERR_INVALIDCALL";		case DSERR_GENERIC: return "DSERR_GENERIC";		case DSERR_PRIOLEVELNEEDED: return "DSERR_PRIOLEVELNEEDED";		case DSERR_OUTOFMEMORY: return "DSERR_OUTOFMEMORY";		case DSERR_BADFORMAT: return "DSERR_BADFORMAT";		case DSERR_UNSUPPORTED: return "DSERR_UNSUPPORTED";		case DSERR_NODRIVER: return "DSERR_NODRIVER";		case DSERR_ALREADYINITIALIZED: return "DSERR_ALREADYINITIALIZED";		case DSERR_NOAGGREGATION: return "DSERR_NOAGGREGATION";		case DSERR_BUFFERLOST: return "DSERR_BUFFERLOST";		case DSERR_OTHERAPPHASPRIO: return "DSERR_OTHERAPPHASPRIO";		case DSERR_UNINITIALIZED: return "DSERR_UNINITIALIZED";		case DSERR_NOINTERFACE: return "DSERR_NOINTERFACE";		case DSERR_ACCESSDENIED: return "DSERR_ACCESSDENIED";		default: return "unknown";	}}/**\brief uninitialize direct sound*/static void UninitDirectSound(void){    // finally release the DirectSound object    if (hds) {    	IDirectSound_Release(hds);    	hds = NULL;    }    // free DSOUND.DLL    if (hdsound_dll) {    	FreeLibrary(hdsound_dll);    	hdsound_dll = NULL;    }	mp_msg(MSGT_AO, MSGL_V, "ao_dsound: DirectSound uninitialized\n");}/**\brief print the commandline help*/static void print_help(){  mp_msg(MSGT_AO, MSGL_FATAL,           "\n-ao dsound commandline help:\n"           "Example: mplayer -ao dsound:device=1\n"           "  sets 1st device\n"           "\nOptions:\n"           "  device=<device-number>\n"           "    Sets device number, use -v to get a list\n");}/**\brief enumerate direct sound devices\return TRUE to continue with the enumeration*/static BOOL CALLBACK DirectSoundEnum(LPGUID guid,LPCSTR desc,LPCSTR module,LPVOID context){    int* device_index=context;    mp_msg(MSGT_AO, MSGL_V,"%i %s ",*device_index,desc);    if(device_num==*device_index){        mp_msg(MSGT_AO, MSGL_V,"<--");        if(guid){            memcpy(&device,guid,sizeof(GUID));        }    }    mp_msg(MSGT_AO, MSGL_V,"\n");    (*device_index)++;    return TRUE;}/**\brief initilize direct sound\return 0 if error, 1 if ok*/static int InitDirectSound(void){	DSCAPS dscaps;	// initialize directsound    HRESULT (WINAPI *OurDirectSoundCreate)(LPGUID, LPDIRECTSOUND *, LPUNKNOWN);	HRESULT (WINAPI *OurDirectSoundEnumerate)(LPDSENUMCALLBACKA, LPVOID);   	int device_index=0;	opt_t subopts[] = {	  {"device", OPT_ARG_INT, &device_num,NULL},	  {NULL}	}; 	if (subopt_parse(ao_subdevice, subopts) != 0) {		print_help();		return 0;	}    	hdsound_dll = LoadLibrary("DSOUND.DLL");	if (hdsound_dll == NULL) {		mp_msg(MSGT_AO, MSGL_ERR, "ao_dsound: cannot load DSOUND.DLL\n");		return 0;	}	OurDirectSoundCreate = (void*)GetProcAddress(hdsound_dll, "DirectSoundCreate");	OurDirectSoundEnumerate = (void*)GetProcAddress(hdsound_dll, "DirectSoundEnumerateA");	if (OurDirectSoundCreate == NULL || OurDirectSoundEnumerate == NULL) {		mp_msg(MSGT_AO, MSGL_ERR, "ao_dsound: GetProcAddress FAILED\n");		FreeLibrary(hdsound_dll);		return 0;	}    	// Enumerate all directsound devices	mp_msg(MSGT_AO, MSGL_V,"ao_dsound: Output Devices:\n");	OurDirectSoundEnumerate(DirectSoundEnum,&device_index);	// Create the direct sound object	if FAILED(OurDirectSoundCreate((device_num)?&device:NULL, &hds, NULL )) {		mp_msg(MSGT_AO, MSGL_ERR, "ao_dsound: cannot create a DirectSound device\n");		FreeLibrary(hdsound_dll);		return 0;	}	/* Set DirectSound Cooperative level, ie what control we want over Windows	 * sound device. In our case, DSSCL_EXCLUSIVE means that we can modify the	 * settings of the primary buffer, but also that only the sound of our	 * application will be hearable when it will have the focus.	 * !!! (this is not really working as intended yet because to set the	 * cooperative level you need the window handle of your application, and	 * I don't know of any easy way to get it. Especially since we might play	 * sound without any video, and so what window handle should we use ???	 * The hack for now is to use the Desktop window handle - it seems to be	 * working */	if (IDirectSound_SetCooperativeLevel(hds, GetDesktopWindow(), DSSCL_EXCLUSIVE)) {		mp_msg(MSGT_AO, MSGL_ERR, "ao_dsound: cannot set direct sound cooperative level\n");		IDirectSound_Release(hds);		FreeLibrary(hdsound_dll);		return 0;	}	mp_msg(MSGT_AO, MSGL_V, "ao_dsound: DirectSound initialized\n");	memset(&dscaps, 0, sizeof(DSCAPS));	dscaps.dwSize = sizeof(DSCAPS);	if (DS_OK == IDirectSound_GetCaps(hds, &dscaps)) {		if (dscaps.dwFlags & DSCAPS_EMULDRIVER) mp_msg(MSGT_AO, MSGL_V, "ao_dsound: DirectSound is emulated, waveOut may give better performance\n");	} else {		mp_msg(MSGT_AO, MSGL_V, "ao_dsound: cannot get device capabilities\n");	}	return 1;}/**\brief destroy the direct sound buffer*/static void DestroyBuffer(void){	if (hdsbuf) {		IDirectSoundBuffer_Release(hdsbuf);		hdsbuf = NULL;	}	if (hdspribuf) {		IDirectSoundBuffer_Release(hdspribuf);		hdspribuf = NULL;	}}/**\brief fill sound buffer\param data pointer to the sound data to copy\param len length of the data to copy in bytes\return number of copyed bytes*/static int write_buffer(unsigned char *data, int len){  HRESULT res;  LPVOID lpvPtr1;   DWORD dwBytes1;   LPVOID lpvPtr2;   DWORD dwBytes2; 

⌨️ 快捷键说明

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