📄 hspdifout.cpp
字号:
//
// Copyright(C) Renesas Technology Corp. 2002-2003. All rights reserved.
//
// sample program for HSpdifTx for ITS-DS7
//
// FILE : HSpdifOut.c
// CREATED : 2002.06.26
// MODIFIED : 2003.12.25
// AUTHOR : Renesas Technology Corp.
// HARDWARE : RENESAS ITS-DS7
// HISTORY :
// 2002.06.26
// - Created release code.
// (based on sample program for HSpdifTx for ITS-DS4 Ver.1.0.0)
// 2003.12.25
// - Supported .wav file.
// - Added parameter.
//
#include <windows.h>
#include <dsound.h>
#include "ioctl_its_ds7.h"
#include "wavefile.h"
#define BUFF_SIZE 0x8000
#define NELEMS(a) (sizeof(a)/sizeof((a)[0]))
#define MRCHECK(r,str,label)\
if ((r != MMSYSERR_NOERROR)) { RETAILMSG(1, (TEXT(#str) TEXT(" failed. mr=%08x\r\n"), r)); mr = r; goto label;}
typedef struct {
unsigned char FName[16];
unsigned long Dmy1[2];
unsigned long SamplingRate1;
unsigned long SamplingRate2;
unsigned short Dmy2;
unsigned short BitsPerSample;
unsigned long Dmy3;
unsigned long Length;
} HEADER;
PBYTE Data;
PTSTR usage_text[] =
{
TEXT("usage:\r\n"),
TEXT(" -f <filename> input filename(.wav file or PCM raw data file)\r\n"),
TEXT(" -b <bitsize> sample bit size(16/20/24)\r\n"),
TEXT(" -? help\r\n"),
TEXT("note:\r\n"),
TEXT(" HSPDIF supported only 44.1kHz stereo.\r\n"),
};
void
Usage(void)
{ int i;
for (i = 0; i < NELEMS(usage_text); i++) {
RETAILMSG(1, (usage_text[i]));
}
}
int WINAPI
WinMain (
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPWSTR lpCmdLine,
int nCmdShow)
{
HANDLE hDevice=NULL;
HANDLE hDriver;
DWORD dwRet;
DWORD dwData;
HANDLE hFile=NULL;
DWORD nCnt;
//HEADER Head;
BOOL RetCode;
DWORD dwBufferSize;
PBYTE pBufferBits = NULL;
PWAVEFORMATEX pwfx = NULL;
DWORD dwRemain;
DWORD dwDuration;
MMRESULT mr;
PTSTR pOption;
TCHAR ws[] = TEXT(" \t");
int errors = 0;
PTSTR pszFilename = TEXT("");
DWORD dwBitSize=16;
DWORD dwLen;
//DWORD dwBytesRead;
DWORD nAvgBytesPerSec;
RETAILMSG(1, (TEXT("SPDIF playback start.\r\n")));
// parse the command line
for (pOption = _tcstok(lpCmdLine, ws); pOption != NULL; pOption = _tcstok(NULL, ws)) {
if (pOption[0] != '/' && pOption[0] != '-') {
RETAILMSG(1, (TEXT("Unrecognized argument %s\r\n"), pOption));
errors++;
continue;
}
PTSTR pParameter = _tcstok(NULL, ws);
if (pParameter == NULL) {
RETAILMSG(1, (TEXT("Missing parameter to option %s\r\n"), pOption));
}
switch (pOption[1]) {
case 'f':
pszFilename = pParameter;
break;
case 'b':
dwBitSize = _ttoi(pParameter);
switch(dwBitSize){
case 16:
case 20:
case 24:
break;
default:
RETAILMSG(1, (TEXT("Illegal sample bit size %d\r\n"),dwBitSize));
errors++;
break;
}
break;
case '?':
case 'h':
Usage();
errors++;
break;
default:
RETAILMSG(1, (TEXT("Unrecognized option %s\r\n"), pOption));
errors++;
break;
}
}
if (errors > 0) {
// we've already issued complaint, now just exit
return -1;
}
dwLen = _tcslen(pszFilename);
if(_tcscmp(pszFilename+dwLen-4,TEXT(".wav")) == 0){
// .wav
mr = ReadWaveFile(pszFilename, &pwfx, &dwBufferSize, &pBufferBits);
MRCHECK(mr, ReadWaveFile, ERROR_RET);
dwDuration = dwBufferSize * 1000 / pwfx->nAvgBytesPerSec;
RETAILMSG(1, (TEXT("\"%s\" %c%02d %5dHz %6d bytes %5d ms\r\n")
, pszFilename
, pwfx->nChannels == 2 ? L'S' : L'M'
, pwfx->wBitsPerSample
, pwfx->nSamplesPerSec
, dwBufferSize
, dwDuration
));
if(pwfx->nSamplesPerSec != 44100 || pwfx->nChannels != 2 || (pwfx->wBitsPerSample != 16 && pwfx->wBitsPerSample != 20 && pwfx->wBitsPerSample != 24)){
RETAILMSG(1, (TEXT("ERROR: Not supported audio format.\r\n")));
goto ERROR_RET;
}
dwBitSize = pwfx->wBitsPerSample;
}
else{
// PCM raw data
hFile = CreateFile(pszFilename, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, 0, NULL);
if ( hFile == INVALID_HANDLE_VALUE ){
RETAILMSG(1, (TEXT("File open failed. rc %d\r\n"), GetLastError()));
return 0;
}
dwBufferSize = GetFileSize (hFile, NULL) ;
nAvgBytesPerSec = (DWORD)((2.0*dwBitSize/8.0) * 44100.0);
dwDuration = dwBufferSize * 1000 / nAvgBytesPerSec;
RETAILMSG(1, (TEXT("\"%s\" S%02d 44100Hz %6d bytes %5d ms\r\n")
, pszFilename
, dwBitSize
, dwBufferSize
, dwDuration
));
pBufferBits = new BYTE[BUFF_SIZE];
if (pBufferBits == NULL) {
RETAILMSG(1, (TEXT("Unable to allocate chunk buffer\r\n")));
goto ERROR_RET;
}
}
hDevice = CreateFile(
TEXT("SPD1:"),
GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if ( hDevice == INVALID_HANDLE_VALUE ){
if ( GetLastError() == ERROR_DEV_NOT_EXIST ){
//register spdif driver
hDriver = RegisterDevice(TEXT("SPD"), 1, TEXT("HSPDIF.DLL"), 0);
if ( !hDriver ){
RETAILMSG(1, (TEXT("Failed to register spdif device driver.\r\n")));
}
hDevice = CreateFile(TEXT("SPD1:"),
GENERIC_WRITE,
0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
}
if ( hDevice == INVALID_HANDLE_VALUE ){
RETAILMSG(1, (TEXT("Failed to open spdif device driver.\r\n")));
goto ERROR_RET;
}
}
switch(dwBitSize){
case 16: dwData = SPDIF_SAMPLE_BIT_SIZE_16; break;
case 20: dwData = SPDIF_SAMPLE_BIT_SIZE_20; break;
case 24: dwData = SPDIF_SAMPLE_BIT_SIZE_24; break;
default: break;
}
switch( dwData ){
case SPDIF_SAMPLE_BIT_SIZE_16:
RETAILMSG(1, (TEXT("Set SampleSize : 16\r\n")));
break;
case SPDIF_SAMPLE_BIT_SIZE_20:
RETAILMSG(1, (TEXT("Set SampleSize : 20\r\n")));
break;
case SPDIF_SAMPLE_BIT_SIZE_24:
RETAILMSG(1, (TEXT("Set SampleSize : 24\r\n")));
break;
default :
break;
}
RetCode = DeviceIoControl(hDevice, IOCTL_SPDIF_SET_TXSAMPLE_SIZE,
&dwData, sizeof(DWORD), NULL, 0, &dwRet, NULL);
if (RetCode == FALSE) {
RETAILMSG(1, (TEXT("Error : IOCTL_SPDIF_SET_TXSAMPLE_SIZE\r\n")));
goto ERROR_RET;
}
DeviceIoControl(hDevice, IOCTL_SPDIF_GET_TXSAMPLE_SIZE,
NULL, 0, &dwData, sizeof(DWORD), &dwRet, NULL);
if (RetCode == FALSE) {
RETAILMSG(1, (TEXT("Error : IOCTL_SPDIF_GET_TXSAMPLE_SIZE\r\n")));
goto ERROR_RET;
}
switch( dwData ){
case SPDIF_SAMPLE_BIT_SIZE_16: dwData = 16;break;
case SPDIF_SAMPLE_BIT_SIZE_20: dwData = 20;break;
case SPDIF_SAMPLE_BIT_SIZE_24: dwData = 24;break;
default : dwData = 0;break;
}
RETAILMSG(1, (TEXT("Get SampleSize : %d\r\n"), dwData));
Data = pBufferBits;
dwRemain = dwBufferSize;
while(1){
if(hFile){
Data = pBufferBits;
if (! ReadFile(hFile, Data, BUFF_SIZE, &nCnt, NULL)) {
RETAILMSG(1, (TEXT("Unable to read data\r\n")));
break;
}
}
else{
nCnt = BUFF_SIZE;
if(dwRemain < BUFF_SIZE){
nCnt = dwRemain;
}
}
// RETAILMSG(1, (TEXT("send:%d/remain:%d/max:%d\r\n"), nCnt, dwRemain,dwBufferSize));
RETRY_TRANS:
dwRet= 0;
RetCode = DeviceIoControl(hDevice, IOCTL_SPDIF_TRANSMITTING_DATA,
Data, nCnt, NULL, 0, &dwRet, NULL);
if (RetCode == FALSE) {
if (GetLastError() == ERROR_INVALID_PARAMETER) {
RETAILMSG(1, (TEXT("Error : IOCTL_SPDIF_TRANSMITTING_DATA - Invalid Params.\r\n")));
break;
} else if (GetLastError() == ERROR_TIMEOUT) {
RETAILMSG(1, (TEXT("Error : IOCTL_SPDIF_TRANSMITTING_DATA - TimeOut.\r\n")));
}
}
if(nCnt > dwRet){
nCnt-=dwRet;
dwRemain-=dwRet;
Data+=dwRet;
goto RETRY_TRANS;
}
if(dwRemain<=dwRet){
break;
}
dwRemain-=dwRet;
if(!hFile){
Data+=dwRet;
}
}
Sleep(4000);
DeviceIoControl(hDevice, IOCTL_SPDIF_STOP_TRANSMIT,
NULL, 0, NULL, 0, &dwRet, NULL);
RETAILMSG(1, (TEXT("SPDIF playback finished.\r\n"),dwBufferSize));
ERROR_RET:
if(hDevice) CloseHandle( hDevice );
if(hFile) CloseHandle( hFile );
if(pBufferBits) delete [] pBufferBits;
if(pwfx) delete [] pwfx;
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -