소프트웨어 자동 변환없이 winmm (waveOutXxxx()
)을 사용하여 44100hz 8 비트 모노 PCM 스트림을 열려고합니다. (이러한 변환으로 인해 발생할 수있는 필터링없이 출력 파형을 완벽하게 제어하려고합니다.)waveOutGetDevCaps()가 할 수있을 때 Windows Vista/latera의 waveOutOpen()이 기본 출력 장치가 44100hz 모노 8 비트 PCM을 재생할 수 없다고 말하는 이유는 무엇입니까?
// 2 september 2014
#define UNICODE
#define _UNICODE
#define STRICT
#define STRICT_TYPED_ITEMIDS
// get Windows version right; right now Windows XP
#define WINVER 0x0501
#define _WIN32_WINNT 0x0501
#define _WIN32_WINDOWS 0x0501 /* according to Microsoft's winperf.h */
#define _WIN32_IE 0x0600 /* according to Microsoft's sdkddkver.h */
#define NTDDI_VERSION 0x05010000 /* according to Microsoft's sdkddkver.h */
#include <windows.h>
#include <stdio.h>
int main(void)
{
HWAVEOUT wo;
HANDLE event;
WAVEFORMATEX fmt;
MMRESULT err;
event = CreateEvent(NULL, TRUE, TRUE, NULL); // start off signaled just in case
if (event == NULL) {
fprintf(stderr, "CreateEvent() failed (last error %d)\n", GetLastError());
return 3;
}
ZeroMemory(&fmt, sizeof (WAVEFORMATEX));
fmt.wFormatTag = WAVE_FORMAT_PCM;
fmt.nChannels = 1;
fmt.nSamplesPerSec = 44100;
fmt.wBitsPerSample = 8;
fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample;
fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign;
fmt.cbSize = 0;
err = waveOutOpen(&wo, WAVE_MAPPER, &fmt,
(DWORD_PTR) event, 0,
CALLBACK_EVENT | WAVE_FORMAT_DIRECT);
if (err != MMSYSERR_NOERROR) {
WCHAR errmsg[MAXERRORLENGTH + 1];
MMRESULT converr;
converr = waveOutGetErrorTextW(err, errmsg, MAXERRORLENGTH + 1);
if (converr != MMSYSERR_NOERROR) {
fprintf(stderr, "open error %x (message conversion error %x)\n", err, converr);
return 2;
}
fwprintf(stderr, L"open error: %s\n", errmsg);
return 1;
}
fprintf(stderr, "open successful\n");
return 0;
}
Windows XP와 와인에서 잘 작동합니다.
// 1 september 2014
#define UNICODE
#define _UNICODE
#define STRICT
#define STRICT_TYPED_ITEMIDS
// get Windows version right; right now Windows XP
#define WINVER 0x0501
#define _WIN32_WINNT 0x0501
#define _WIN32_WINDOWS 0x0501 /* according to Microsoft's winperf.h */
#define _WIN32_IE 0x0600 /* according to Microsoft's sdkddkver.h */
#define NTDDI_VERSION 0x05010000 /* according to Microsoft's sdkddkver.h */
#include <windows.h>
#include <stdio.h>
int main(void)
{
MMRESULT err;
WAVEOUTCAPS caps;
ZeroMemory(&caps, sizeof (WAVEOUTCAPS));
err = waveOutGetDevCaps((DWORD_PTR) WAVE_MAPPER, &caps, sizeof (WAVEOUTCAPS));
if (err != MMSYSERR_NOERROR) {
fprintf(stderr, "mmsys err %x\n", err);
return 1;
}
printf("formats: ");
#define FORMATS(x) if((caps.dwFormats & x) != 0) printf("%s ", #x);
FORMATS(WAVE_FORMAT_1M08);
FORMATS(WAVE_FORMAT_1M16);
FORMATS(WAVE_FORMAT_1S08);
FORMATS(WAVE_FORMAT_1S16);
FORMATS(WAVE_FORMAT_2M08);
FORMATS(WAVE_FORMAT_2M16);
FORMATS(WAVE_FORMAT_2S08);
FORMATS(WAVE_FORMAT_2S16);
FORMATS(WAVE_FORMAT_4M08);
FORMATS(WAVE_FORMAT_4M16);
FORMATS(WAVE_FORMAT_4S08);
FORMATS(WAVE_FORMAT_4S16);
FORMATS(WAVE_FORMAT_96M08);
FORMATS(WAVE_FORMAT_96M16);
FORMATS(WAVE_FORMAT_96S08);
FORMATS(WAVE_FORMAT_96S16);
printf("\n");
printf("channels: %d\n", caps.wChannels);
printf("supports: ");
#define SUPPORTS(x) if((caps.dwSupport & x) != 0) printf("%s ", #x);
SUPPORTS(WAVECAPS_LRVOLUME);
SUPPORTS(WAVECAPS_PITCH);
SUPPORTS(WAVECAPS_PLAYBACKRATE);
SUPPORTS(WAVECAPS_SYNC);
SUPPORTS(WAVECAPS_VOLUME);
SUPPORTS(WAVECAPS_SAMPLEACCURATE);
printf("\n");
return 0;
}
를 지금 출력은
formats: WAVE_FORMAT_1M08 WAVE_FORMAT_1M16 WAVE_FORMAT_1S08 WAVE_FORMAT_1S16 WAVE_FORMAT_2M08 WAVE_FORMAT_2M16 WAVE_FORMAT_2S08 WAVE_FORMAT_2S16 WAVE_FORMAT_4M08 WAVE_FORMAT_4M16 WAVE_FORMAT_4S08 WAVE_FORMAT_4S16 WAVE_FORMAT_96M08 WAVE_FORMAT_96M16 WAVE_FORMAT_96S08 WAVE_FORMAT_96S16
channels: 2
supports: WAVECAPS_LRVOLUME WAVECAPS_VOLUME WAVECAPS_SAMPLEACCURATE
이다 : 그러나 Windows Vista 및 새로운 (시도 비스타, 7, 8.1)에, 나는
open error: The specified format is not supported or cannot be translated. Use the Capabilities function to determine the supported formats.
을 얻을 그럼 그렇게하자 ... 대기하지만 WAVE_FORMAT_4M08
은 지원 목록에 있습니다!
무엇을 제공합니까? 감사.
아차, 내 나쁜 . 감사! – andlabs