void fluid_win32_destroy_window(void) { HWND hwnd = fluid_win32_get_window(); if (hwnd) { DestroyWindow(hwnd); fluid_wnd = 0; } }
/* * new_fluid_dsound_audio_driver */ fluid_audio_driver_t* new_fluid_dsound_audio_driver(fluid_settings_t* settings, fluid_synth_t* synth) { HRESULT hr; DSBUFFERDESC desc; fluid_dsound_audio_driver_t* dev = NULL; DSCAPS caps; char *buf1; DWORD bytes1; double sample_rate; int periods, period_size; fluid_dsound_devsel_t devsel; /* check if the globals are initialized */ if (FLUID_HINSTANCE == NULL) { FLUID_LOG(FLUID_ERR, "FluidSynth hinstance not set, which is needed for DirectSound"); return NULL; } /* if (fluid_wnd == NULL) { if (fluid_win32_create_window() != 0) { FLUID_LOG(FLUID_ERR, "Couldn't create window needed for DirectSound"); return NULL; } } */ /* create and clear the driver data */ dev = FLUID_NEW(fluid_dsound_audio_driver_t); if (dev == NULL) { FLUID_LOG(FLUID_ERR, "Out of memory"); return NULL; } FLUID_MEMSET(dev, 0, sizeof(fluid_dsound_audio_driver_t)); dev->synth = synth; dev->cont = 1; fluid_settings_getnum(settings, "synth.sample-rate", &sample_rate); fluid_settings_getint(settings, "audio.periods", &periods); fluid_settings_getint(settings, "audio.period-size", &period_size); /* check the format */ if (!fluid_settings_str_equal(settings, "audio.sample-format", "16bits")) { FLUID_LOG(FLUID_ERR, "Unhandled sample format"); goto error_recovery; } dev->frame_size = 2 * sizeof(short); dev->buffer_byte_size = period_size * dev->frame_size; dev->queue_byte_size = periods * dev->buffer_byte_size; dev->write = fluid_synth_write_s16; /* create and initialize the buffer format */ dev->format = (WAVEFORMATEX*) FLUID_MALLOC(sizeof(WAVEFORMATEX)); if (dev->format == NULL) { FLUID_LOG(FLUID_ERR, "Out of memory"); goto error_recovery; } ZeroMemory(dev->format, sizeof(WAVEFORMATEX)); dev->format->wFormatTag = WAVE_FORMAT_PCM; dev->format->nChannels = 2; dev->format->wBitsPerSample = 16; dev->format->nSamplesPerSec = (DWORD) sample_rate; dev->format->nBlockAlign = (WORD) dev->frame_size; dev->format->nAvgBytesPerSec = dev->format->nSamplesPerSec * dev->frame_size; dev->format->cbSize = 0; devsel.devGUID = NULL; /* get the selected device name. if none is specified, use NULL for the default device. */ if(fluid_settings_dupstr(settings, "audio.dsound.device", &devsel.devname) == FLUID_OK /* ++ alloc device name */ && devsel.devname && strlen (devsel.devname) > 0) { /* look for the GUID of the selected device */ DirectSoundEnumerate((LPDSENUMCALLBACK) fluid_dsound_enum_callback2, (void *)&devsel); } if (devsel.devname) FLUID_FREE (devsel.devname); /* -- free device name */ /* open DirectSound */ hr = DirectSoundCreate(devsel.devGUID, &dev->direct_sound, NULL); if (hr != DS_OK) { FLUID_LOG(FLUID_ERR, "Failed to create the DirectSound object"); goto error_recovery; } hr = IDirectSound_SetCooperativeLevel(dev->direct_sound, fluid_win32_get_window(), DSSCL_PRIORITY); if (hr != DS_OK) { FLUID_LOG(FLUID_ERR, "Failed to set the cooperative level"); goto error_recovery; } caps.dwSize = sizeof(caps); hr = IDirectSound_GetCaps(dev->direct_sound, &caps); if (hr != DS_OK) { FLUID_LOG(FLUID_ERR, "Failed to query the device capacities"); goto error_recovery; } /* create primary buffer */ ZeroMemory(&desc, sizeof(DSBUFFERDESC)); desc.dwSize = sizeof(DSBUFFERDESC); desc.dwFlags = DSBCAPS_PRIMARYBUFFER; if (caps.dwFreeHwMixingStreamingBuffers > 0) { desc.dwFlags |= DSBCAPS_LOCHARDWARE; } hr = IDirectSound_CreateSoundBuffer(dev->direct_sound, &desc, &dev->prim_buffer, NULL); if (hr != DS_OK) { FLUID_LOG(FLUID_ERR, "Failed to allocate the primary buffer"); goto error_recovery; } /* set the primary sound buffer to this format. if it fails, just print a warning. */ hr = IDirectSoundBuffer_SetFormat(dev->prim_buffer, dev->format); if (hr != DS_OK) { FLUID_LOG(FLUID_WARN, "Can't set format of primary sound buffer", fluid_win32_error(hr)); } /* initialize the buffer description */ ZeroMemory(&desc, sizeof(DSBUFFERDESC)); desc.dwSize = sizeof(DSBUFFERDESC); desc.dwFlags = DSBCAPS_GLOBALFOCUS | DSBCAPS_GETCURRENTPOSITION2; desc.lpwfxFormat = dev->format; desc.dwBufferBytes = dev->queue_byte_size; desc.dwReserved = 0; if (caps.dwFreeHwMixingStreamingBuffers > 0) { desc.dwFlags |= DSBCAPS_LOCHARDWARE; } /* create the secondary sound buffer */ hr = IDirectSound_CreateSoundBuffer(dev->direct_sound, &desc, &dev->sec_buffer, NULL); if (hr != DS_OK) { FLUID_LOG(FLUID_ERR, "dsound: Can't create sound buffer: %s", fluid_win32_error(hr)); goto error_recovery; } /* Lock */ hr = IDirectSoundBuffer_Lock(dev->sec_buffer, 0, 0, (void*) &buf1, &bytes1, 0, 0, DSBLOCK_ENTIREBUFFER); if ((hr != DS_OK) || (buf1 == NULL)) { FLUID_LOG(FLUID_PANIC, "Failed to lock the audio buffer. Exiting."); goto error_recovery; } /* fill the buffer with silence */ memset(buf1, 0, bytes1); /* Unlock */ IDirectSoundBuffer_Unlock(dev->sec_buffer, buf1, bytes1, 0, 0); /* start the audio thread */ dev->thread = CreateThread(NULL, 0, &fluid_dsound_audio_run, (LPVOID) dev, 0, &dev->threadID); if (dev->thread == NULL) { goto error_recovery; } return (fluid_audio_driver_t*) dev; error_recovery: delete_fluid_dsound_audio_driver((fluid_audio_driver_t*) dev); return NULL; }