bool SoundManager::Init(HWND hwnd) {
	bool result;
	/*
		First init the DirectSound API as well as the primary buffer.
		Then LoadWaveFile can be called which will load in the .wav audio file and init the secondary buffer with the audio info.
		After loading is complete then PlayWaveFile is called which then plays the .wav file once.
	*/

	// Init direct sound and the primary buffer
	result = InitDirectSound(hwnd);
	if (!result) {
		return false;
	}
	
	
	// Load the background music
	result = LoadWaveFile("Sound\\ElectroSong.wav", &mBGMusic1Buffer);
	if (!result) {
		return false;
	}
	

	// Load a wave audio file onto a secondary buffer
	result = LoadWaveFile("Sound\\quack.wav", &mSecondBuffer);
	if (!result) {
		return false;
	}

	return true;
}
Ejemplo n.º 2
0
unsigned long	GS_PlayStream(unsigned long nPort,HWND hWnd)
{
	//初始化渲染设备,开启线程
	PSTREAMCONFIG pm = GetStream(nPort);
	if(pm==NULL)
	{
		return S_FALSE;
	}
	if(pm->pVideoConfig)
	{
		//初始化视频渲染设备
		pm->pVideoConfig->m_hWnd = hWnd;
		if(InitDirectDraw(pm->pVideoConfig,1920,1080)==S_FALSE)
		{
			pm->nLastError = GENTEK_DDRAW_INIT_FAILED;
			if(InitGDIPlus(pm->pVideoConfig)==S_FALSE)
			{
				pm->nLastError = GENTEK_VIDEO_RENDER_FAILED;
				return S_FALSE;
			}
			else
			{
				pm->pVideoConfig->m_bUsingGDIPLUS = true;
			}
		}
		else
		{
			pm->pVideoConfig->m_bUsingGDIPLUS = false;
		}
	}
	if(pm->pAudioConfig)
	{
		//为初始化音频做准备
		pm->pAudioConfig->m_hwnd = pm->pVideoConfig->m_hWnd;
		//初始化音频设备
		if(InitDirectSound(pm->pAudioConfig)==S_FALSE)
		{
			pm->nLastError = GENTEK_AUDIO_RENDER_FAILED;
			return S_FALSE;
		}

	}
	//创建线程
	pm->pContrlConfig->nPort = nPort;
	pm->pContrlConfig->bDataOver = false;
	pm->pContrlConfig->bCallStreamOver = false;
	if(PlayStream(pm->pContrlConfig,pm->pCodecConfig,pm->pVideoConfig,pm->pAudioConfig)==S_OK)
	{
		char str[128];
		sprintf(str," Play GentekPlatformStream %d\n",nPort);
		OutputDebugStringA(str);
		return S_OK;
	}

	pm->nLastError = GENTEK_THREAD_CREAT_FAILED;
	return S_FALSE;
}
Ejemplo n.º 3
0
bool Sound::Init(HWND hWnd, char *soundFile)
{
    bool result ;
    result = InitDirectSound(hWnd);
    if (!result)
    {
        return false;
    }

    //Load a wave audio file
    result = LoadWaveFile(soundFile, &pSecondaryBuffer);
    if (!result)
    {
        return false;
    }

    return true;
}
Ejemplo n.º 4
0
/**
\brief setup sound device
\param rate samplerate
\param channels number of channels
\param format format
\param flags unused
\return 0=success -1=fail
*/
static int init(struct ao *ao)
{
    struct priv *p = ao->priv;
    int res;

    if (!InitDirectSound(ao))
        return -1;

    ao->no_persistent_volume = true;
    p->audio_volume = 100;

    // ok, now create the buffers
    WAVEFORMATEXTENSIBLE wformat;
    DSBUFFERDESC dsbpridesc;
    DSBUFFERDESC dsbdesc;
    int format = af_fmt_from_planar(ao->format);
    int rate = ao->samplerate;

    if (AF_FORMAT_IS_AC3(format))
        format = AF_FORMAT_AC3;
    else {
        struct mp_chmap_sel sel = {0};
        mp_chmap_sel_add_waveext(&sel);
        if (!ao_chmap_sel_adjust(ao, &sel, &ao->channels))
            return -1;
    }
    switch (format) {
    case AF_FORMAT_AC3:
    case AF_FORMAT_S24_LE:
    case AF_FORMAT_S16_LE:
    case AF_FORMAT_U8:
        break;
    default:
        MP_VERBOSE(ao, "format %s not supported defaulting to Signed 16-bit Little-Endian\n",
                   af_fmt_to_str(format));
        format = AF_FORMAT_S16_LE;
    }
    //set our audio parameters
    ao->samplerate = rate;
    ao->format = format;
    ao->bps = ao->channels.num * rate * (af_fmt2bits(format) >> 3);
    int buffersize = ao->bps; // space for 1 sec
    MP_VERBOSE(ao, "Samplerate:%iHz Channels:%i Format:%s\n", rate,
               ao->channels.num, af_fmt_to_str(format));
    MP_VERBOSE(ao, "Buffersize:%d bytes (%d msec)\n",
               buffersize, buffersize / ao->bps * 1000);

    //fill waveformatex
    ZeroMemory(&wformat, sizeof(WAVEFORMATEXTENSIBLE));
    wformat.Format.cbSize = (ao->channels.num > 2)
                    ? sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX) : 0;
    wformat.Format.nChannels = ao->channels.num;
    wformat.Format.nSamplesPerSec = rate;
    if (AF_FORMAT_IS_AC3(format)) {
        wformat.Format.wFormatTag = WAVE_FORMAT_DOLBY_AC3_SPDIF;
        wformat.Format.wBitsPerSample = 16;
        wformat.Format.nBlockAlign = 4;
    } else {
        wformat.Format.wFormatTag = (ao->channels.num > 2)
                                    ? WAVE_FORMAT_EXTENSIBLE : WAVE_FORMAT_PCM;
        wformat.Format.wBitsPerSample = af_fmt2bits(format);
        wformat.Format.nBlockAlign = wformat.Format.nChannels *
                                     (wformat.Format.wBitsPerSample >> 3);
    }

    // fill in primary sound buffer descriptor
    memset(&dsbpridesc, 0, sizeof(DSBUFFERDESC));
    dsbpridesc.dwSize = sizeof(DSBUFFERDESC);
    dsbpridesc.dwFlags       = DSBCAPS_PRIMARYBUFFER;
    dsbpridesc.dwBufferBytes = 0;
    dsbpridesc.lpwfxFormat   = NULL;

    // fill in the secondary sound buffer (=stream buffer) descriptor
    memset(&dsbdesc, 0, sizeof(DSBUFFERDESC));
    dsbdesc.dwSize = sizeof(DSBUFFERDESC);
    dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 /** Better position accuracy */
                      | DSBCAPS_GLOBALFOCUS       /** Allows background playing */
                      | DSBCAPS_CTRLVOLUME;       /** volume control enabled */

    if (ao->channels.num > 2) {
        wformat.dwChannelMask = mp_chmap_to_waveext(&ao->channels);
        wformat.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
        wformat.Samples.wValidBitsPerSample = wformat.Format.wBitsPerSample;
        // Needed for 5.1 on emu101k - shit soundblaster
        dsbdesc.dwFlags |= DSBCAPS_LOCHARDWARE;
    }
    wformat.Format.nAvgBytesPerSec = wformat.Format.nSamplesPerSec *
                                     wformat.Format.nBlockAlign;

    dsbdesc.dwBufferBytes = buffersize;
    dsbdesc.lpwfxFormat = (WAVEFORMATEX *)&wformat;
    p->buffer_size = dsbdesc.dwBufferBytes;
    p->write_offset = 0;
    p->min_free_space = wformat.Format.nBlockAlign;
    p->outburst = wformat.Format.nBlockAlign * 512;

    // create primary buffer and set its format

    res = IDirectSound_CreateSoundBuffer(p->hds, &dsbpridesc, &p->hdspribuf, NULL);
    if (res != DS_OK) {
        UninitDirectSound(ao);
        MP_ERR(ao, "cannot create primary buffer (%s)\n", dserr2str(res));
        return -1;
    }
    res = IDirectSoundBuffer_SetFormat(p->hdspribuf, (WAVEFORMATEX *)&wformat);
    if (res != DS_OK) {
        MP_WARN(ao, "cannot set primary buffer format (%s), using "
                "standard setting (bad quality)", dserr2str(res));
    }

    MP_VERBOSE(ao, "primary buffer created\n");

    // now create the stream buffer

    res = IDirectSound_CreateSoundBuffer(p->hds, &dsbdesc, &p->hdsbuf, NULL);
    if (res != DS_OK) {
        if (dsbdesc.dwFlags & DSBCAPS_LOCHARDWARE) {
            // Try without DSBCAPS_LOCHARDWARE
            dsbdesc.dwFlags &= ~DSBCAPS_LOCHARDWARE;
            res = IDirectSound_CreateSoundBuffer(p->hds, &dsbdesc, &p->hdsbuf, NULL);
        }
        if (res != DS_OK) {
            UninitDirectSound(ao);
            MP_ERR(ao, "cannot create secondary (stream)buffer (%s)\n",
                   dserr2str(res));
            return -1;
        }
    }
    MP_VERBOSE(ao, "secondary (stream)buffer created\n");
    return 0;
}
Ejemplo n.º 5
0
void VDAudioOutputDirectSoundW32::ThreadRun() {
	if (!InitDirectSound()) {
		ShutdownDirectSound();
		mMutex.Lock();
		mbThreadInited = true;
		mbThreadInitSucceeded = false;
		mMutex.Unlock();
		mUpdateEvent.signal();
		return;
	}

	ThreadState threadState = kThreadStateStop;
	uint32 lastInitCount = 0;
	bool underflow = false;
	bool playing = false;
	uint32 dsStreamWritePosition = 0;

	if (!InitPlayback()) {
		ShutdownDirectSound();

		mMutex.Lock();
		mbThreadInited = true;
		mbThreadInitSucceeded = false;
		mMutex.Unlock();
		mUpdateEvent.signal();
		return;
	}

	mMutex.Lock();
	mbThreadInited = true;
	mbThreadInitSucceeded = true;
	mUpdateEvent.signal();
	mMutex.Unlock();

	for(;;) {
		if (playing)
			mUpdateEvent.tryWait(10);
		else
			mUpdateEvent.wait();

		mMutex.Lock();
		threadState = (ThreadState)mThreadState;
		mMutex.Unlock();

		if (threadState == kThreadStatePlay) {
			if (!underflow) {
				StartPlayback();
				playing = true;
			}
		} else {
			StopPlayback();
			playing = false;
		}

		if (threadState == kThreadStateExit)
			break;

		if (!playing)
			continue;

		Cursors cursors;
		if (!ReadCursors(cursors))
			continue;

		uint32 level;
		mMutex.Lock();
		level = mBufferLevel;

		// Compute current buffering level.
		sint32 bufferedLevel = mDSWriteCursor - cursors.mPlayCursor;
		if (bufferedLevel > (sint32)mDSBufferSizeHalf)
			bufferedLevel -= mDSBufferSize;
		else if (bufferedLevel < -(sint32)mDSBufferSizeHalf)
			bufferedLevel += mDSBufferSize;

		if (bufferedLevel < 0) {
			bufferedLevel = 0;
			mDSWriteCursor = cursors.mWriteCursor;
		}

		// Compute the stream play position. This should never go backward. If it
		// has, we have underflowed.
		uint32 newDSStreamPlayPos = dsStreamWritePosition - bufferedLevel;

		if (newDSStreamPlayPos < mDSStreamPlayPosition) {
			mDSStreamPlayPosition = dsStreamWritePosition;
			bufferedLevel = 0;
		}

		mDSBufferedBytes = bufferedLevel;

		mMutex.Unlock();

		if (!level) {
			if (!underflow && playing) {
				// Check for underflow.
				if (!bufferedLevel) {
					StopPlayback();
					playing = false;
				}
			}

			continue;
		}

		// compute how many bytes to copy
		uint32 toCopy = level;
		if (toCopy + bufferedLevel > mDSBufferSizeHalf)
			toCopy = mDSBufferSizeHalf - bufferedLevel;

		if (!toCopy)
			continue;

		// update local write position
		dsStreamWritePosition += toCopy;

		// lock and copy into DirectSound buffer
		const uint8 *src = mBuffer.data();
		uint32 consumed = 0;
		while(toCopy > 0) {
			const uint32 tc2 = std::min<uint32>(toCopy, mBufferSize - mBufferReadOffset);
			const uint32 tc3 = std::min<uint32>(tc2, mDSBufferSize - mDSWriteCursor);

			WriteAudio(mDSWriteCursor, src + mBufferReadOffset, tc3);
			mBufferReadOffset += tc3;
			if (mBufferReadOffset >= mBufferSize)
				mBufferReadOffset = 0;

			mDSWriteCursor += tc3;
			if (mDSWriteCursor >= mDSBufferSize)
				mDSWriteCursor = 0;

			toCopy -= tc3;
			consumed += tc3;
		}

		mMutex.Lock();
		mBufferLevel -= consumed;
		mMutex.Unlock();

		// restart playback if we were in underflow state
		if (underflow && !playing) {
			underflow = false;
			playing = true;

			StartPlayback();
		}

		mResponseEvent.signal();
	}

	ShutdownPlayback();
	ShutdownDirectSound();
}