/** \brief close audio device \param immed stop playback immediately */ static void uninit(struct ao *ao) { reset(ao); DestroyBuffer(ao); UninitDirectSound(ao); }
unsigned long GS_StopStream(unsigned long nPort) { //恢复渲染,停止线程 PSTREAMCONFIG pm = GetStream(nPort); if(pm==NULL) { return S_FALSE; } if(StopStream(pm->pContrlConfig)==S_OK) { if(pm->pAudioConfig) UninitDirectSound(pm->pAudioConfig); if(pm->pVideoConfig->m_bUsingGDIPLUS) { UnInitGDIPlus(pm->pVideoConfig); } else { UnInitDirectDraw(pm->pVideoConfig); } } char str[128]; sprintf(str," Stop GentekPlatformStream %d\n",nPort); OutputDebugStringA(str); return S_OK; }
/** \brief close audio device \param immed stop playback immediately */ static void uninit(struct ao *ao, bool immed) { if (!immed) mp_sleep_us(get_delay(ao) * 1000000); reset(ao); DestroyBuffer(ao); UninitDirectSound(ao); }
/** \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; }