开发者

how can I record from the audio input of a PC being accessed via remote desktop?

I am writing an application, in Borland Turbo C++ (2006) and running under Windows XP Pro, in which I want to record from the audio input into a data buffer so that I can subsequently FFT the time response.

When the application is run locally the following code works fine:

short int       pluck_data[T_SAMPLES][CHANNELS];

//---------------------------------------------------------------------------

int __fastcall CheckResult(char* func_name, int result)
{
  int   return_value = 1;           // set return_value for fail by default
  char  msg[100];

  if(result == MMSYSERR_NOERROR)    // function call returned without error
    return_value = 0;
  else                              // function call returned error
  {
    switch(result)
    {
      case MMSYSERR_ALLOCATED:
        sprintf(msg, "%s: Specified resource is already allocated.", func_name);
        break;
      case MMSYSERR_BADDEVICEID:
        sprintf(msg, "%s: Specified device identifier is out of range.", func_name);
        break;
      case MMSYSERR_INVALHANDLE:
        sprintf(msg, "%s: Specified device handle is invalid.", func_name);
        break;
      case MMSYSERR_NODRIVER:
        sprintf(msg, "%s: No device driver is present.", func_name);
        break;
      case MMSYSERR_NOMEM:
        sprintf(msg, "%s: Unable to allocate or lock memory.", func_name);
        break;
      case WAVERR_BADFORMAT:
        sprintf(msg, "%s: Attempted to open with an unsupported waveform-audio format.", func_name);
        break;
      case WAVERR_STILLPLAYING:
        sprintf(msg, "%s: The buffer pointed to by the pwh parameter is still in the queue.", func_name);
        break;
      case WAVERR_UNPREPARED:
        sprintf(msg, "%s: The buffer pointed to by the pwh parameter hasn't been prepared.", func_name);
        break;
      default:
        sprintf(msg, "%s: Unknown error.", func_name);
    }
    ReportError(hWnd, msg, log_fptr);
  } // else function call returned error
  return return_value;
}

//---------------------------------------------------------------------------

int __fastcall RecordString()
{
  int           return_value = 1;           // set return_value for fail by default
  WAVEINCAPS    dev_capability;
  HWAVEIN       dev_handle;
  WAVEFORMATEX  rec_format;
开发者_JAVA百科  WAVEHDR       rec_header;
  int           result;
  char          msg[100];

  result = waveInGetNumDevs();      // get number of audio input devices
  if(result != 1)
  {
    if(result == 0)
      sprintf(msg, "No waveform-audio input devices present.");
    else
      sprintf(msg, "More than one waveform-audio input device present.");
    ReportError(hWnd, msg, log_fptr);
  }
  else
  {
    // only 1 audio input device; test its capabilities
    result = waveInGetDevCaps(0,&dev_capability,sizeof(dev_capability));
    if(CheckResult("waveInGetDevCaps", result) == 0)
    {
      // test if device supports 96kHz, Stereo, 16-bit format WAVE_FORMAT_96S16
      if ((dev_capability.dwFormats & WAVE_FORMAT_96S16) == 0)
      {
        sprintf(msg, "waveInGetDevCaps: WAVE_FORMAT_96S16 not supported");
        ReportError(hWnd, msg, log_fptr);
      }
      else
      {
        // initialise required record format
        rec_format.wFormatTag = WAVE_FORMAT_PCM;
        rec_format.nChannels = CHANNELS;                                    // 2
        rec_format.nSamplesPerSec = SAMPLE_RATE;                            // 96000
        rec_format.nAvgBytesPerSec = BYTES_PER_SAMPLE * SAMPLE_RATE;        // 384000
        rec_format.nBlockAlign = BYTES_PER_SAMPLE;                          // 4
        rec_format.wBitsPerSample = SAMPLE_BITS;                            // 16
        rec_format.cbSize = 0;
        // open audio input device requesting format 96kHz, Stereo, 16-bit
        result = waveInOpen(&dev_handle, WAVE_MAPPER, &rec_format, 0, 0, 0);
        if(CheckResult("waveInOpen", result) == 0)
        {
          // initialise header for data buffer
          rec_header.lpData = (char*)&pluck_data;
          rec_header.dwBufferLength = sizeof(pluck_data);
          rec_header.dwFlags = 0;
          // prepare header for data buffer
          result = waveInPrepareHeader(dev_handle, &rec_header, sizeof(rec_header));
          if(CheckResult("waveInPrepareHeader", result) == 0)
          {
            // connect data buffer to audio input device
            result = waveInAddBuffer(dev_handle, &rec_header, sizeof(rec_header));
            if(CheckResult("waveInAddBuffer", result) == 0)
            {
              // start recording
              result = waveInStart(dev_handle);
              if(CheckResult("waveInStart", result) == 0)
              {
                // recording - poll flag until data buffer full
                while((rec_header.dwFlags & WHDR_DONE ) == 0); // wait for flag to be set
                // buffer now full
                // reset/stop recording
                result = waveInReset(dev_handle);
                if(CheckResult("waveInReset", result) == 0)
                {
                  // unprepare header for data buffer
                  result = waveInUnprepareHeader(dev_handle, &rec_header, sizeof(rec_header));
                  if(CheckResult("waveInUnprepareHeader", result) == 0)
                  {
                    // close audio input device
                    result = waveInClose(dev_handle);
                    if(CheckResult("waveInClose", result) == 0)
                      return_value = 0;
                  }
                }
              }
            }
          }
        }
      }
    }
  }
  return return_value;
}

But if I try to run this program via Remote Desktop (from a PC running Win XP Home) the call to waveInGetNumDevs() returns zero.

As an alternative I removed the calls to waveInGetNumDevs(), waveInGetDevCaps(), and waveInOpen() from the RecordString() function and instead run these just once when the program starts. (The call to waveInClose() was also removed from RecordString().) Now, if I start the program on the host PC so that it has successfully called waveInOpen() and retrieved the handle to the audio input device (HWAVEIN dev_handle), I can then switch to accessing this host PC via Remote Desktop (while the program is still running) and the RecordString() function still works OK. So it would seem that the audio input is available via Remote Desktop once the device handle has been obtained; the problem is getting the handle.

Is there a way that I can run the whole application via Remote Desktop, instead of having to start it locally at the host PC?


I found the answer thanks to: http://www.wikihow.com/Hear-Audio-from-the-Remote-PC-when-Using-Remote-Desktop

When starting Remote Desktop click on the "Options" button, then select the "Local Resources" tab, and ensure that "Remote computer sound" is set to "Leave at remote computer".

The original code shown in the question now works ok when run via Remote Desktop.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜