Я пишу приложение на Borland Turbo C ++ (2006) и работаю под Windows XP Pro, в котором я хочу выполнить запись с аудиовхода в буфер данных, чтобы впоследствии я мог БПФ преобразовать время отклика.
Когда приложение запускается локально, следующий код работает нормально:
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;
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;
}
Но если я попытаюсь запустить эту программу через удаленный рабочий стол (с ПК с Win XP Home), вызов waveInGetNumDevs () вернет ноль.
В качестве альтернативы я удалил вызовы waveInGetNumDevs (), waveInGetDevCaps () и waveInOpen () из функции RecordString () и вместо этого запустил их только один раз при запуске программы. (Вызов waveInClose () также был удален из RecordString ().) Теперь, если я запустил программу на главном ПК, чтобы она успешно вызвала waveInOpen () и извлекла дескриптор на устройство ввода звука (HWAVEIN dev_handle), Затем я могу переключиться на доступ к этому хост-компьютеру через удаленный рабочий стол (пока программа еще работает), и функция RecordString () по-прежнему работает нормально. Поэтому может показаться, что аудиовход доступен через удаленный рабочий стол после получения дескриптора устройства; проблема в получении ручки.
Есть ли способ, с помощью которого я могу запустить все приложение через удаленный рабочий стол вместо того, чтобы запускать его локально на главном ПК?