Beispiel #1
0
static int DX5_OpenAudio(_THIS, SDL_AudioSpec *spec)
{
	HRESULT      result;
	WAVEFORMATEX waveformat;

	/* Set basic WAVE format parameters */
	memset(&waveformat, 0, sizeof(waveformat));
	waveformat.wFormatTag = WAVE_FORMAT_PCM;

	/* Determine the audio parameters from the AudioSpec */
	switch ( spec->format & 0xFF ) {
		case 8:
			/* Unsigned 8 bit audio data */
			spec->format = AUDIO_U8;
			silence = 0x80;
			waveformat.wBitsPerSample = 8;
			break;
		case 16:
			/* Signed 16 bit audio data */
			spec->format = AUDIO_S16;
			silence = 0x00;
			waveformat.wBitsPerSample = 16;
			break;
		default:
			SDL_SetError("Unsupported audio format");
			return(-1);
	}
	waveformat.nChannels = spec->channels;
	waveformat.nSamplesPerSec = spec->freq;
	waveformat.nBlockAlign =
		waveformat.nChannels * (waveformat.wBitsPerSample/8);
	waveformat.nAvgBytesPerSec = 
		waveformat.nSamplesPerSec * waveformat.nBlockAlign;

	/* Update the fragment size as size in bytes */
	SDL_CalculateAudioSpec(spec);

	/* Open the audio device */
	result = DSoundCreate(NULL, &sound, NULL);
	if ( result != DS_OK ) {
		SetDSerror("DirectSoundCreate", result);
		return(-1);
	}

	/* Create the audio buffer to which we write */
	NUM_BUFFERS = -1;
#ifdef USE_PRIMARY_BUFFER
	if ( mainwin ) {
		NUM_BUFFERS = CreatePrimary(sound, mainwin, &mixbuf,
						&waveformat, spec->size);
	}
#endif /* USE_PRIMARY_BUFFER */
	if ( NUM_BUFFERS < 0 ) {
		NUM_BUFFERS = CreateSecondary(sound, mainwin, &mixbuf,
						&waveformat, spec->size);
		if ( NUM_BUFFERS < 0 ) {
			return(-1);
		}
#ifdef DEBUG_SOUND
		fprintf(stderr, "Using secondary audio buffer\n");
#endif
	}
#ifdef DEBUG_SOUND
	else
		fprintf(stderr, "Using primary audio buffer\n");
#endif

	/* The buffer will auto-start playing in DX5_WaitAudio() */
	playing = 0;
	mixlen = spec->size;

#ifdef USE_POSITION_NOTIFY
	/* See if we can use DirectX 6 event notification */
	if ( CreateAudioEvent(this) == 0 ) {
		this->WaitAudio = DX6_WaitAudio_EventWait;
	} else {
		this->WaitAudio = DX5_WaitAudio_BusyWait;
	}
#endif
	return(0);
}
static int
DSOUND_OpenDevice(_THIS, const char *devname, int iscapture)
{
    HRESULT result;
    WAVEFORMATEX waveformat;
    int valid_format = 0;
    SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);

    /* !!! FIXME: handle devname */
    /* !!! FIXME: handle iscapture */

    /* Initialize all variables that we clean on shutdown */
    this->hidden = (struct SDL_PrivateAudioData *)
        SDL_malloc((sizeof *this->hidden));
    if (this->hidden == NULL) {
        SDL_OutOfMemory();
        return 0;
    }
    SDL_memset(this->hidden, 0, (sizeof *this->hidden));

    while ((!valid_format) && (test_format)) {
        switch (test_format) {
        case AUDIO_U8:
        case AUDIO_S16:
        case AUDIO_S32:
            this->spec.format = test_format;
            valid_format = 1;
            break;
        }
        test_format = SDL_NextAudioFormat();
    }

    if (!valid_format) {
        DSOUND_CloseDevice(this);
        SDL_SetError("DirectSound: Unsupported audio format");
        return 0;
    }

    SDL_memset(&waveformat, 0, sizeof(waveformat));
    waveformat.wFormatTag = WAVE_FORMAT_PCM;
    waveformat.wBitsPerSample = SDL_AUDIO_BITSIZE(this->spec.format);
    waveformat.nChannels = this->spec.channels;
    waveformat.nSamplesPerSec = this->spec.freq;
    waveformat.nBlockAlign =
        waveformat.nChannels * (waveformat.wBitsPerSample / 8);
    waveformat.nAvgBytesPerSec =
        waveformat.nSamplesPerSec * waveformat.nBlockAlign;

    /* Update the fragment size as size in bytes */
    SDL_CalculateAudioSpec(&this->spec);

    /* Open the audio device */
    result = DSoundCreate(NULL, &this->hidden->sound, NULL);
    if (result != DS_OK) {
        DSOUND_CloseDevice(this);
        SetDSerror("DirectSoundCreate", result);
        return 0;
    }

    /* Create the audio buffer to which we write */
    this->hidden->num_buffers = CreateSecondary(this, mainwin, &waveformat);
    if (this->hidden->num_buffers < 0) {
        DSOUND_CloseDevice(this);
        return 0;
    }

    /* The buffer will auto-start playing in DSOUND_WaitDevice() */
    this->hidden->mixlen = this->spec.size;

    return 1;                   /* good to go. */
}
bool DirectSound::init()
{
  HRESULT hr;

  dsoundDLL = LoadLibrary("DSOUND.DLL");
  HRESULT (WINAPI *DSoundCreate)(LPCGUID,LPDIRECTSOUND *,IUnknown *);  
  if(dsoundDLL != NULL) {    
    DSoundCreate = (HRESULT (WINAPI *)(LPCGUID,LPDIRECTSOUND *,IUnknown *))
      GetProcAddress(dsoundDLL, "DirectSoundCreate");
    
    if(DSoundCreate == NULL) {
      theApp.directXMessage("DirectSoundCreate");
      return false;
    }
  } else {
    theApp.directXMessage("DSOUND.DLL");
    return false;
  }
  
  if((hr = DSoundCreate(NULL,&pDirectSound,NULL) != DS_OK)) {
    //    errorMessage(myLoadString(IDS_ERROR_SOUND_CREATE), hr);
    systemMessage(IDS_CANNOT_CREATE_DIRECTSOUND,
                  "Cannot create DirectSound %08x", hr);
    pDirectSound = NULL;
    dsbSecondary = NULL;
    return false;
  }

  if((hr=pDirectSound->SetCooperativeLevel((HWND)*theApp.m_pMainWnd,
                                           DSSCL_EXCLUSIVE)) != DS_OK) {
    //    errorMessage(myLoadString(IDS_ERROR_SOUND_LEVEL), hr);
    systemMessage(IDS_CANNOT_SETCOOPERATIVELEVEL,
                  "Cannot SetCooperativeLevel %08x", hr);
    return false;
  }

  DSBUFFERDESC dsbdesc;
  ZeroMemory(&dsbdesc,sizeof(DSBUFFERDESC));
  dsbdesc.dwSize=sizeof(DSBUFFERDESC);
  dsbdesc.dwFlags = DSBCAPS_PRIMARYBUFFER;
  
  if((hr=pDirectSound->CreateSoundBuffer(&dsbdesc,
                                         &dsbPrimary,
                                         NULL) != DS_OK)) {
    //    errorMessage(myLoadString(IDS_ERROR_SOUND_BUFFER),hr);
    systemMessage(IDS_CANNOT_CREATESOUNDBUFFER,
                  "Cannot CreateSoundBuffer %08x", hr);
    return false;
  }
  
  // Set primary buffer format

  memset(&wfx, 0, sizeof(WAVEFORMATEX)); 
  wfx.wFormatTag = WAVE_FORMAT_PCM; 
  wfx.nChannels = 2;
  switch(soundQuality) {
  case 2:
    wfx.nSamplesPerSec = 22050;
    soundBufferLen = 736*2;
    soundBufferTotalLen = 7360*2;
    break;
  case 4:
    wfx.nSamplesPerSec = 11025;
    soundBufferLen = 368*2;
    soundBufferTotalLen = 3680*2;
    break;
  default:
    soundQuality = 1;
    wfx.nSamplesPerSec = 44100;
    soundBufferLen = 1470*2;
    soundBufferTotalLen = 14700*2;
  }
  wfx.wBitsPerSample = 16; 
  wfx.nBlockAlign = (wfx.wBitsPerSample / 8) * wfx.nChannels;
  wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;

  if((hr = dsbPrimary->SetFormat(&wfx)) != DS_OK) {
    //    errorMessage(myLoadString(IDS_ERROR_SOUND_PRIMARY),hr);
    systemMessage(IDS_CANNOT_SETFORMAT_PRIMARY,
                  "Cannot SetFormat for primary %08x", hr);
    return false;
  }
  
  ZeroMemory(&dsbdesc,sizeof(DSBUFFERDESC));  
  dsbdesc.dwSize = sizeof(DSBUFFERDESC);
  dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2|DSBCAPS_CTRLPOSITIONNOTIFY;
  dsbdesc.dwBufferBytes = soundBufferTotalLen;
  dsbdesc.lpwfxFormat = &wfx;

  if((hr = pDirectSound->CreateSoundBuffer(&dsbdesc, &dsbSecondary, NULL))
     != DS_OK) {
    dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2;
    if((hr = pDirectSound->CreateSoundBuffer(&dsbdesc, &dsbSecondary, NULL))
       != DS_OK) {
      systemMessage(IDS_CANNOT_CREATESOUNDBUFFER_SEC,
                    "Cannot CreateSoundBuffer secondary %08x", hr);
      return false;
    }
  }

  dsbSecondary->SetCurrentPosition(0);

  if(!theApp.useOldSync) {
    hr = dsbSecondary->QueryInterface(IID_IDirectSoundNotify,
                                      (void **)&dsbNotify);
    if(!FAILED(hr)) {
      dsbEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
      
      DSBPOSITIONNOTIFY notify[10];
      
      for(int i = 0; i < 10; i++) {
        notify[i].dwOffset = i*soundBufferLen;
        notify[i].hEventNotify = dsbEvent;
      }
      if(FAILED(dsbNotify->SetNotificationPositions(10, notify))) {
        dsbNotify->Release();
        dsbNotify = NULL;
        CloseHandle(dsbEvent);
        dsbEvent = NULL;
      }
    }
  }
  
  hr = dsbPrimary->Play(0,0,DSBPLAY_LOOPING);

  if(hr != DS_OK) {
    //    errorMessage(myLoadString(IDS_ERROR_SOUND_PLAYPRIM), hr);
    systemMessage(IDS_CANNOT_PLAY_PRIMARY, "Cannot Play primary %08x", hr);
    return false;
  }

  systemSoundOn = true;
  
  return true;
}