int audioStreamer_ds::Open(int iswrite, int srate, int nch, int bps, int sleep, int nbufs, int bufsize, GUID *device)
{
  // todo: use device
  m_sleep = sleep >= 0 ? sleep : 0;

  GUID zero={0,};
  if (!memcmp(device,&zero,sizeof(zero))) device=NULL;

  m_nch = nch;
  m_srate=srate;
  m_bps=bps;

  int fmt_align=(bps>>3)*nch;
  int fmt_mul=fmt_align*srate;
  WAVEFORMATEX wfx={
		WAVE_FORMAT_PCM,
		nch,
		srate,
		fmt_mul,
		fmt_align,
		bps,
		0
	};
  m_totalbufsize=nbufs*bufsize;

  if (iswrite)
  {
      DirectSoundCreate(device,&m_lpds,NULL);

      if (m_lpds)
      {
        HWND hWnd = GetForegroundWindow();
        if (hWnd == NULL) hWnd = GetDesktopWindow();
        m_lpds->SetCooperativeLevel(hWnd,DSSCL_PRIORITY);

        // create a secondary buffer for now
        DSBUFFERDESC ds={sizeof(ds),DSBCAPS_GETCURRENTPOSITION2|DSBCAPS_GLOBALFOCUS,m_totalbufsize,0,&wfx, };
        m_lpds->CreateSoundBuffer(&ds,&m_outbuf,NULL);
        
      }

  }
  else
  {
    DirectSoundCaptureCreate(device,&m_lpcap,NULL);
    if (m_lpcap)
    {
      DSCBUFFERDESC ds={sizeof(ds),0,m_totalbufsize,0,&wfx, };
      m_lpcap->CreateCaptureBuffer(&ds,&m_inbuf,NULL);
    }
  }

  m_bufsize=bufsize;


  return 0;
}
Beispiel #2
0
static int capture_init (void)
{
	HRESULT hr;
	DSCBUFFERDESC sound_buffer_rec;
	WAVEFORMATEX wavfmt;
	TCHAR *name;
	int samplerate = 44100;

	if (currprefs.sampler_freq)
		samplerate = currprefs.sampler_freq;

	name = record_devices[currprefs.win32_samplersoundcard]->name;

	wavfmt.wFormatTag = WAVE_FORMAT_PCM;
	wavfmt.nChannels = 2;
	wavfmt.nSamplesPerSec = samplerate;
	wavfmt.wBitsPerSample = 16;
	wavfmt.nBlockAlign = wavfmt.wBitsPerSample / 8 * wavfmt.nChannels;
	wavfmt.nAvgBytesPerSec = wavfmt.nBlockAlign * wavfmt.nSamplesPerSec;
	wavfmt.cbSize = 0;

	clockspersample = sampler_evtime / samplerate;
	sampleframes = (samplerate + 49) / 50;
	recordbufferframes = 16384;
	if (currprefs.sampler_buffer)
		recordbufferframes = currprefs.sampler_buffer;

	hr = DirectSoundCaptureCreate (&record_devices[currprefs.win32_samplersoundcard]->guid, &lpDS2r, NULL);
	if (FAILED (hr)) {
		write_log (_T("SAMPLER: DirectSoundCaptureCreate('%s') failure: %s\n"), name, DXError (hr));
		return 0;
	}
	memset (&sound_buffer_rec, 0, sizeof (DSCBUFFERDESC));
	sound_buffer_rec.dwSize = sizeof (DSCBUFFERDESC);
	sound_buffer_rec.dwBufferBytes = recordbufferframes * SAMPLESIZE;
	sound_buffer_rec.lpwfxFormat = &wavfmt;
	sound_buffer_rec.dwFlags = 0 ;

	hr = lpDS2r->CreateCaptureBuffer (&sound_buffer_rec, &lpDSB2r, NULL);
	if (FAILED (hr)) {
		write_log (_T("SAMPLER: CreateCaptureSoundBuffer('%s') failure: %s\n"), name, DXError(hr));
		return 0;
	}

	hr = lpDSB2r->Start (DSCBSTART_LOOPING);
	if (FAILED (hr)) {
		write_log (_T("SAMPLER: DirectSoundCaptureBuffer_Start('%s') failed: %s\n"), name, DXError (hr));
		return 0;
	}
	samplebuffer = xcalloc (uae_u8, sampleframes * SAMPLESIZE);
	write_log (_T("SAMPLER: Parallel port sampler initialized, CPS=%f, '%s'\n"), clockspersample, name);
	return 1;
}
Beispiel #3
0
static void capture_free (void)
{
	if (lpDSB2r) {
		lpDSB2r->Stop ();
		lpDSB2r->Release ();
		write_log (_T("SAMPLER: Parallel port sampler freed\n"));
	}
	lpDSB2r = NULL;
	if (lpDS2r)
		lpDS2r->Release ();
	lpDS2r = NULL;
	xfree (samplebuffer);
	samplebuffer = NULL;
}
void VoiceRecord_DSound::Term()
{
	if(m_pCaptureBuffer)
		m_pCaptureBuffer->Release();

	if(m_pCapture)
		m_pCapture->Release();

	if(m_hWrapEvent)
		DeleteObject(m_hWrapEvent);

	if(m_hInstDS)
	{
		FreeLibrary(m_hInstDS);
		m_hInstDS = NULL;
	}

	Clear();
}
bool nuiAudioDevice_DirectSound::Open(std::vector<uint32>& rInputChannels, std::vector<uint32>& rOutputChannels, double SampleRate, uint32 BufferSize, nuiAudioProcessFn pProcessFunction)
{
  if (!mpDirectSound)
    return false;
  
  HRESULT hr = S_OK;
  mAudioProcessFn = pProcessFunction;

  mBufferSize = BufferSize;

  hr = mpDirectSound->SetCooperativeLevel(GetDesktopWindow(), DSSCL_EXCLUSIVE);

  mHasInput = (rInputChannels.size() > 0) && (mInputChannels.size() > 0);
  mHasOutput = (rOutputChannels.size() > 0) && (mOutputChannels.size() > 0);


  mpInputBuffer = NULL;
  mpOutputBuffer = NULL;

  if (!mHasInput && !mHasOutput)
    return false;

  // init ringbuffer
  mpRingBuffer = new nglRingBuffer(BufferSize*4, sizeof(float), rOutputChannels.size());
  mpRingBuffer->AdvanceWriteIndex(BufferSize);

  // init input buffers
  if (mHasInput)
  {
    {
      mActiveInputChannels = rInputChannels;
    }

    WAVEFORMATEX IFormat;
    IFormat.wFormatTag = WAVE_FORMAT_PCM;
    IFormat.nChannels = (WORD)mInputChannels.size();
    IFormat.nSamplesPerSec = ToNearest(SampleRate);
    IFormat.wBitsPerSample = 16;
    IFormat.nAvgBytesPerSec = IFormat.nChannels * IFormat.nSamplesPerSec * (IFormat.wBitsPerSample / 8);
    IFormat.nBlockAlign = IFormat.nChannels * (IFormat.wBitsPerSample / 8);
    IFormat.cbSize = 0;

    DSCBUFFERDESC IBufferDesc;
    memset(&IBufferDesc, 0, sizeof(IBufferDesc));
    IBufferDesc.dwSize = sizeof(DSCBUFFERDESC);
    IBufferDesc.dwFlags = DSCBCAPS_WAVEMAPPED;
    IBufferDesc.dwBufferBytes = (IFormat.wBitsPerSample / 8) * IFormat.nChannels * BufferSize * 2;
    IBufferDesc.dwReserved = 0;
    IBufferDesc.lpwfxFormat = &IFormat;
    IBufferDesc.dwFXCount = 0;
    IBufferDesc.lpDSCFXDesc = NULL;

    NGL_ASSERT(mpDirectSoundCapture);
    hr = mpDirectSoundCapture->CreateCaptureBuffer(&IBufferDesc, &mpInputBuffer, NULL);
  }


  // init output buffers
  if (mHasOutput)
  {
    {
      mActiveOutputChannels = rOutputChannels;
    }

    WAVEFORMATEX OFormat;
    OFormat.wFormatTag = WAVE_FORMAT_PCM;
    OFormat.nChannels = (WORD)mOutputChannels.size();
    OFormat.nSamplesPerSec = ToNearest(SampleRate);
    OFormat.wBitsPerSample = 16;
    OFormat.nAvgBytesPerSec = OFormat.nChannels * OFormat.nSamplesPerSec * (OFormat.wBitsPerSample / 8);
    OFormat.nBlockAlign = OFormat.nChannels * OFormat.wBitsPerSample / 8;
    OFormat.cbSize = 0;

    DSBUFFERDESC  OBufferDesc;
    memset(&OBufferDesc, 0, sizeof(OBufferDesc));
    OBufferDesc.dwSize = sizeof(OBufferDesc);
    OBufferDesc.dwFlags = DSBCAPS_GLOBALFOCUS | DSBCAPS_CTRLPOSITIONNOTIFY;
    OBufferDesc.dwBufferBytes = (OFormat.wBitsPerSample / 8) * OFormat.nChannels * BufferSize * 2;
    OBufferDesc.dwReserved = 0;
    OBufferDesc.lpwfxFormat = &OFormat;

    hr = mpDirectSound->CreateSoundBuffer(&OBufferDesc, &mpOutputBuffer, NULL);
  }


  // create event for notifications
  mNotifInputEvent[0] = CreateEvent(NULL, FALSE, FALSE, _T("NUI_DSoundInputEvent0"));
  mNotifInputEvent[1] = CreateEvent(NULL, FALSE, FALSE, _T("NUI_DSoundInputEvent1"));
  mNotifOutputEvent[0] = CreateEvent(NULL, FALSE, FALSE, _T("NUI_DSoundOutputEvent0"));
  mNotifOutputEvent[1] = CreateEvent(NULL, FALSE, FALSE, _T("NUI_DSoundOutputEvent1"));




  // set the notification for the input buffer
  if (mHasInput)
  {
    // Setup the notification positions
    ZeroMemory( &mInputPosNotify, sizeof(DSBPOSITIONNOTIFY) * 2);
    mInputPosNotify[0].dwOffset = BufferSize * sizeof(int16) * mInputChannels.size() - 1;
    mInputPosNotify[0].hEventNotify = mNotifInputEvent[0];             
    mInputPosNotify[1].dwOffset = BufferSize * sizeof(int16) * mInputChannels.size() * 2 - 1;
    mInputPosNotify[1].hEventNotify = mNotifInputEvent[1];           

    LPDIRECTSOUNDNOTIFY pInputNotify = NULL;
    if( FAILED( hr = mpInputBuffer->QueryInterface( IID_IDirectSoundNotify, (VOID**)&pInputNotify ) ) )
    {
      NGL_LOG(_T("nuiAudioDevice_DirectSound"), NGL_LOG_ERROR, _T("Open ERROR : failed in querying interface for input notifications.\n"));
      return false;
    }


    // Tell DirectSound when to notify us. the notification will come in the from 
    // of signaled events that are handled in WinMain()
    if( FAILED( hr = pInputNotify->SetNotificationPositions( 2, mInputPosNotify ) ) )
    {
      NGL_LOG(_T("nuiAudioDevice_DirectSound"), NGL_LOG_ERROR, _T("Open ERROR : failed in setting notifications for input\n"));
      return false;
    }

    pInputNotify->Release();
  }



  // set the notification events for the output buffer
  if (mHasOutput)
  {
    // Setup the notification positions
    ZeroMemory( &mOutputPosNotify, sizeof(DSBPOSITIONNOTIFY) * 2);
    mOutputPosNotify[0].dwOffset = BufferSize * sizeof(int16) * mOutputChannels.size() - 1;
    mOutputPosNotify[0].hEventNotify = mNotifOutputEvent[0];             
    mOutputPosNotify[1].dwOffset = BufferSize * sizeof(int16) * mOutputChannels.size() * 2 - 1;
    mOutputPosNotify[1].hEventNotify = mNotifOutputEvent[1];    

    LPDIRECTSOUNDNOTIFY pOutputNotify = NULL;
    if( FAILED( hr = mpOutputBuffer->QueryInterface( IID_IDirectSoundNotify, (VOID**)&pOutputNotify ) ) )
    {
      NGL_LOG(_T("nuiAudioDevice_DirectSound"), NGL_LOG_ERROR, _T("Open ERROR : failed in querying interface for output notifications.\n"));
      return false;
    }

    // Tell DirectSound when to notify us. the notification will come in the from 
    // of signaled events that are handled in WinMain()
    if( FAILED( hr = pOutputNotify->SetNotificationPositions( 2, mOutputPosNotify ) ) )
    {
      NGL_LOG(_T("nuiAudioDevice_DirectSound"), NGL_LOG_ERROR, _T("Open ERROR : failed in setting notifications for output\n"));
      return false;
    }

    pOutputNotify->Release();
  }


  // start input processing thread
  mpProcessingTh = new nuiAudioDevice_DS_ProcessingTh(this, mNotifInputEvent[0], mNotifInputEvent[1], mAudioProcessFn);
  mpProcessingTh->Start();



  // start output thread
  if (mHasOutput)
  {
    mpOutputTh = new nuiAudioDevice_DS_OutputTh(this, mNotifInputEvent[0], mNotifInputEvent[1], mNotifOutputEvent[0], mNotifOutputEvent[1]);
    mpOutputTh->Start();
    hr = mpOutputBuffer->Play(0,0,DSCBSTART_LOOPING);
    if (FAILED(hr))
      NGL_LOG(_T("nuiAudioDevice_DirectSound"), NGL_LOG_ERROR, _T("OutputBuffer->Play ERROR!\n"));
  }

  // start input capture
  if (mHasInput)
  {
    hr = mpInputBuffer->Start(DSCBSTART_LOOPING);
    if (FAILED(hr))
      NGL_LOG(_T("nuiAudioDevice_DirectSound"), NGL_LOG_ERROR, _T("InputBuffer->Start ERROR!\n"));    
  }





  return true;
}
void nuiAudioDevice_DirectSound::Init()
{
  DSCCAPS icaps;
  icaps.dwSize = sizeof(DSCCAPS);
  if (mpDirectSoundCapture)
    mpDirectSoundCapture->GetCaps(&icaps);
  else
  {
    icaps.dwChannels = 0;
    icaps.dwFormats = 0;
    icaps.dwFlags = 0;
  }

  DSCAPS ocaps;
  ocaps.dwSize = sizeof(DSCAPS);
  mpDirectSound->GetCaps(&ocaps);

  // Input channels:
  if (icaps.dwChannels == 1)
  {
    nglString str(mInName);
    str.Add(_T(" (Input)"));
    mInputChannels.push_back(str);
  }
  else if (icaps.dwChannels > 1)
  {
    {
      nglString str(mInName);
      str.Add(_T(" (Left input)"));
      mInputChannels.push_back(str);
    }

    {
      nglString str(mInName);
      str.Add(_T(" (Right input)"));
      mInputChannels.push_back(str);
    }
  }



  // Output channels:
  {
    nglString str(mOutName);
    str.Add(_T(" (Left output)"));
    mOutputChannels.push_back(str);
  }
  {
    nglString str(mOutName);
    str.Add(_T(" (Right output)"));
    mOutputChannels.push_back(str);
  }

  mSampleRates.clear();
  mBufferSizes.clear();

  if ( ( ( icaps.dwFormats & WAVE_FORMAT_1M16 ) || ( icaps.dwFormats & WAVE_FORMAT_1S16 ) )
    && ocaps.dwMinSecondarySampleRate <= 11025 && ocaps.dwMaxSecondarySampleRate >= 11025 )
    mSampleRates.push_back(11025);
  if ( ( ( icaps.dwFormats & WAVE_FORMAT_2M16 ) || ( icaps.dwFormats & WAVE_FORMAT_2S16 ) )
    && ocaps.dwMinSecondarySampleRate <= 22050 && ocaps.dwMaxSecondarySampleRate >= 22050 )
    mSampleRates.push_back(22050);
  if ( ( ( icaps.dwFormats & WAVE_FORMAT_4M16 ) || ( icaps.dwFormats & WAVE_FORMAT_4S16 ) )
    && ocaps.dwMinSecondarySampleRate <= 44100 && ocaps.dwMaxSecondarySampleRate >= 44100 )
    mSampleRates.push_back(44100);
  if ( ( ( icaps.dwFormats & WAVE_FORMAT_48M16 ) || ( icaps.dwFormats & WAVE_FORMAT_48S16 ) )
    && ocaps.dwMinSecondarySampleRate <= 48000 && ocaps.dwMaxSecondarySampleRate >= 48000 )
    mSampleRates.push_back(48000);
  if ( ( ( icaps.dwFormats & WAVE_FORMAT_96M16 ) || ( icaps.dwFormats & WAVE_FORMAT_96S16 ) )
    && ocaps.dwMinSecondarySampleRate <= 96000 && ocaps.dwMaxSecondarySampleRate >= 96000 )
    mSampleRates.push_back(96000);

  if (mSampleRates.empty())
  {
    mInputChannels.clear();
    if (ocaps.dwMinSecondarySampleRate <= 11025 && ocaps.dwMaxSecondarySampleRate >= 11025 )
      mSampleRates.push_back(11025);
    if (ocaps.dwMinSecondarySampleRate <= 22050 && ocaps.dwMaxSecondarySampleRate >= 22050 )
      mSampleRates.push_back(22050);
    if (ocaps.dwMinSecondarySampleRate <= 44100 && ocaps.dwMaxSecondarySampleRate >= 44100 )
      mSampleRates.push_back(44100);
    if (ocaps.dwMinSecondarySampleRate <= 48000 && ocaps.dwMaxSecondarySampleRate >= 48000 )
      mSampleRates.push_back(48000);
    if (ocaps.dwMinSecondarySampleRate <= 96000 && ocaps.dwMaxSecondarySampleRate >= 96000 )
      mSampleRates.push_back(96000);
  }

  mIsPresent = true;

  uint i = 0;
  int sizes[] = { 64, 128, 256, 384, 512, 768, 1024, 2048, 4096, 8192, 16384, 32768 ,0 };
  while (sizes[i])
    mBufferSizes.push_back(sizes[i++]);
}
bool VoiceRecord_DSound::Init(int sampleRate)
{
	HRESULT hr;
	DSCBUFFERDESC dscDesc;
	DirectSoundCaptureCreateFn createFn;

	
	Term();


	WAVEFORMATEX recordFormat =
	{
		WAVE_FORMAT_PCM,		// wFormatTag
		1,						// nChannels
		sampleRate,				// nSamplesPerSec
		sampleRate*2,			// nAvgBytesPerSec
		2,						// nBlockAlign
		16,						// wBitsPerSample
		sizeof(WAVEFORMATEX)	// cbSize
	};


	
	// Load the DSound DLL.
	m_hInstDS = LoadLibrary("dsound.dll");
	if(!m_hInstDS)
		goto HandleError;

	createFn = (DirectSoundCaptureCreateFn)GetProcAddress(m_hInstDS, "DirectSoundCaptureCreate");
	if(!createFn)
		goto HandleError;

	hr = createFn(NULL, &m_pCapture, NULL);
	if(FAILED(hr))
		goto HandleError;

	// Create the capture buffer.
	memset(&dscDesc, 0, sizeof(dscDesc));
	dscDesc.dwSize = sizeof(dscDesc);
	dscDesc.dwFlags = 0;
	dscDesc.dwBufferBytes = recordFormat.nAvgBytesPerSec;
	dscDesc.lpwfxFormat = &recordFormat;

	hr = m_pCapture->CreateCaptureBuffer(&dscDesc, &m_pCaptureBuffer, NULL);
	if(FAILED(hr))
		goto HandleError;


	// Figure out how many bytes we got in our capture buffer.
	DSCBCAPS caps;
	memset(&caps, 0, sizeof(caps));
	caps.dwSize = sizeof(caps);

	hr = m_pCaptureBuffer->GetCaps(&caps);
	if(FAILED(hr))
		goto HandleError;

	m_nCaptureBufferBytes = caps.dwBufferBytes;


	// Set it up so we get notification when the buffer wraps.
	m_hWrapEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
	if(!m_hWrapEvent)
		goto HandleError;

	DSBPOSITIONNOTIFY dsbNotify;
	dsbNotify.dwOffset = dscDesc.dwBufferBytes - 1;
	dsbNotify.hEventNotify = m_hWrapEvent;
	
	// Get the IDirectSoundNotify interface.
	LPDIRECTSOUNDNOTIFY pNotify;
	hr = m_pCaptureBuffer->QueryInterface(IID_IDirectSoundNotify, (void**)&pNotify);
	if(FAILED(hr))
		goto HandleError;
	
	hr = pNotify->SetNotificationPositions(1, &dsbNotify);
	pNotify->Release();
	if(FAILED(hr))
		goto HandleError;

	// Start capturing.
	hr = m_pCaptureBuffer->Start(DSCBSTART_LOOPING);
	if(FAILED(hr))
		return false;

	return true;


HandleError:;
	Term();
	return false;
}