- Added support for Sun Audio files in wave-file handler.
- Fallback to mmioOpenA if mmopOpenW doesn't work (when using Win9x DLLs).
This commit is contained in:
parent
ea150db949
commit
645a36ceed
|
@ -44,6 +44,46 @@ WINE_DEFAULT_DEBUG_CHANNEL(avifile);
|
|||
|
||||
/***********************************************************************/
|
||||
|
||||
#define ENDIAN_SWAPWORD(x) ((((x) >> 8) & 0xFF) | (((x) & 0xFF) << 8))
|
||||
#define ENDIAN_SWAPDWORD(x) (ENDIAN_SWAPWORD((x >> 16) & 0xFFFF) | \
|
||||
ENDIAN_SWAPWORD(x & 0xFFFF) << 16)
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#define BE2H_WORD(x) (x)
|
||||
#define BE2H_DWORD(x) (x)
|
||||
#define LE2H_WORD(x) ENDIAN_SWAPWORD(x)
|
||||
#define LE2H_DWORD(x) ENDIAN_SWAPDWORD(x)
|
||||
#else
|
||||
#define BE2H_WORD(x) ENDIAN_SWAPWORD(x)
|
||||
#define BE2H_DWORD(x) ENDIAN_SWAPDWORD(x)
|
||||
#define LE2H_WORD(x) (x)
|
||||
#define LE2H_DWORD(x) (x)
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
FOURCC fccType;
|
||||
DWORD offset;
|
||||
DWORD size;
|
||||
INT encoding;
|
||||
DWORD sampleRate;
|
||||
DWORD channels;
|
||||
} SUNAUDIOHEADER;
|
||||
|
||||
#define AU_ENCODING_ULAW_8 1
|
||||
#define AU_ENCODING_PCM_8 2
|
||||
#define AU_ENCODING_PCM_16 3
|
||||
#define AU_ENCODING_PCM_24 4
|
||||
#define AU_ENCODING_PCM_32 5
|
||||
#define AU_ENCODING_FLOAT 6
|
||||
#define AU_ENCODING_DOUBLE 7
|
||||
#define AU_ENCODING_ADPCM_G721_32 23
|
||||
#define AU_ENCODING_ADPCM_G722 24
|
||||
#define AU_ENCODING_ADPCM_G723_24 25
|
||||
#define AU_ENCODING_ADPCM_G723_5 26
|
||||
#define AU_ENCODING_ALAW_8 27
|
||||
|
||||
/***********************************************************************/
|
||||
|
||||
static HRESULT WINAPI IAVIFile_fnQueryInterface(IAVIFile* iface,REFIID refiid,LPVOID *obj);
|
||||
static ULONG WINAPI IAVIFile_fnAddRef(IAVIFile* iface);
|
||||
static ULONG WINAPI IAVIFile_fnRelease(IAVIFile* iface);
|
||||
|
@ -547,8 +587,20 @@ static HRESULT WINAPI IPersistFile_fnLoad(IPersistFile *iface,
|
|||
|
||||
/* try to open the file */
|
||||
This->hmmio = mmioOpenW(This->szFileName, NULL, MMIO_ALLOCBUF | dwMode);
|
||||
if (This->hmmio == NULL) {
|
||||
/* mmioOpenW not in native DLLs of Win9x -- try mmioOpenA */
|
||||
LPSTR szFileName = LocalAlloc(LPTR, len * sizeof(CHAR));
|
||||
if (szFileName == NULL)
|
||||
return AVIERR_MEMORY;
|
||||
|
||||
WideCharToMultiByte(CP_ACP, 0, This->szFileName, -1, szFileName,
|
||||
len, NULL, NULL);
|
||||
|
||||
This->hmmio = mmioOpenA(szFileName, NULL, MMIO_ALLOCBUF | dwMode);
|
||||
LocalFree((HLOCAL)szFileName);
|
||||
if (This->hmmio == NULL)
|
||||
return AVIERR_FILEOPEN;
|
||||
}
|
||||
|
||||
memset(& This->fInfo, 0, sizeof(This->fInfo));
|
||||
memset(& This->sInfo, 0, sizeof(This->sInfo));
|
||||
|
@ -1068,9 +1120,131 @@ static HRESULT AVIFILE_LoadFile(IAVIFileImpl *This)
|
|||
|
||||
static HRESULT AVIFILE_LoadSunFile(IAVIFileImpl *This)
|
||||
{
|
||||
FIXME(": pherhaps sun-audio file -- not implemented !\n");
|
||||
SUNAUDIOHEADER auhdr;
|
||||
|
||||
mmioSeek(This->hmmio, 0, SEEK_SET);
|
||||
if (mmioRead(This->hmmio, (HPSTR)&auhdr, sizeof(auhdr)) != sizeof(auhdr))
|
||||
return AVIERR_FILEREAD;
|
||||
|
||||
if (auhdr.fccType == 0x0064732E) {
|
||||
/* header in little endian */
|
||||
This->ckData.dwDataOffset = LE2H_DWORD(auhdr.offset);
|
||||
This->ckData.cksize = LE2H_DWORD(auhdr.size);
|
||||
|
||||
auhdr.encoding = LE2H_DWORD(auhdr.encoding);
|
||||
auhdr.sampleRate = LE2H_DWORD(auhdr.sampleRate);
|
||||
auhdr.channels = LE2H_DWORD(auhdr.channels);
|
||||
} else if (auhdr.fccType == mmioFOURCC('.','s','n','d')) {
|
||||
/* header in big endian */
|
||||
This->ckData.dwDataOffset = BE2H_DWORD(auhdr.offset);
|
||||
This->ckData.cksize = BE2H_DWORD(auhdr.size);
|
||||
|
||||
auhdr.encoding = BE2H_DWORD(auhdr.encoding);
|
||||
auhdr.sampleRate = BE2H_DWORD(auhdr.sampleRate);
|
||||
auhdr.channels = BE2H_DWORD(auhdr.channels);
|
||||
} else
|
||||
return AVIERR_FILEREAD;
|
||||
|
||||
if (auhdr.channels < 1)
|
||||
return AVIERR_BADFORMAT;
|
||||
|
||||
/* get size of header */
|
||||
switch(auhdr.encoding) {
|
||||
case AU_ENCODING_ADPCM_G721_32:
|
||||
This->cbFormat = sizeof(G721_ADPCMWAVEFORMAT); break;
|
||||
case AU_ENCODING_ADPCM_G723_24:
|
||||
This->cbFormat = sizeof(G723_ADPCMWAVEFORMAT); break;
|
||||
case AU_ENCODING_ADPCM_G722:
|
||||
case AU_ENCODING_ADPCM_G723_5:
|
||||
WARN("unsupported Sun audio format %d\n", auhdr.encoding);
|
||||
return AVIERR_UNSUPPORTED; /* FIXME */
|
||||
default:
|
||||
This->cbFormat = sizeof(WAVEFORMATEX); break;
|
||||
};
|
||||
|
||||
This->lpFormat =
|
||||
(LPWAVEFORMATEX)GlobalAllocPtr(GMEM_MOVEABLE, This->cbFormat);
|
||||
if (This->lpFormat == NULL)
|
||||
return AVIERR_MEMORY;
|
||||
|
||||
This->lpFormat->nChannels = auhdr.channels;
|
||||
This->lpFormat->nSamplesPerSec = auhdr.sampleRate;
|
||||
switch(auhdr.encoding) {
|
||||
case AU_ENCODING_ULAW_8:
|
||||
This->lpFormat->wFormatTag = WAVE_FORMAT_MULAW;
|
||||
This->lpFormat->wBitsPerSample = 8;
|
||||
break;
|
||||
case AU_ENCODING_PCM_8:
|
||||
This->lpFormat->wFormatTag = WAVE_FORMAT_PCM;
|
||||
This->lpFormat->wBitsPerSample = 8;
|
||||
break;
|
||||
case AU_ENCODING_PCM_16:
|
||||
This->lpFormat->wFormatTag = WAVE_FORMAT_PCM;
|
||||
This->lpFormat->wBitsPerSample = 16;
|
||||
break;
|
||||
case AU_ENCODING_PCM_24:
|
||||
This->lpFormat->wFormatTag = WAVE_FORMAT_PCM;
|
||||
This->lpFormat->wBitsPerSample = 24;
|
||||
break;
|
||||
case AU_ENCODING_PCM_32:
|
||||
This->lpFormat->wFormatTag = WAVE_FORMAT_PCM;
|
||||
This->lpFormat->wBitsPerSample = 32;
|
||||
break;
|
||||
case AU_ENCODING_ALAW_8:
|
||||
This->lpFormat->wFormatTag = WAVE_FORMAT_ALAW;
|
||||
This->lpFormat->wBitsPerSample = 8;
|
||||
break;
|
||||
case AU_ENCODING_ADPCM_G721_32:
|
||||
This->lpFormat->wFormatTag = WAVE_FORMAT_G721_ADPCM;
|
||||
This->lpFormat->wBitsPerSample = (3*5*8);
|
||||
This->lpFormat->nBlockAlign = 15*15*8;
|
||||
This->lpFormat->cbSize = sizeof(WORD);
|
||||
((LPG721_ADPCMWAVEFORMAT)This->lpFormat)->nAuxBlockSize = 0;
|
||||
break;
|
||||
case AU_ENCODING_ADPCM_G723_24:
|
||||
This->lpFormat->wFormatTag = WAVE_FORMAT_G723_ADPCM;
|
||||
This->lpFormat->wBitsPerSample = (3*5*8);
|
||||
This->lpFormat->nBlockAlign = 15*15*8;
|
||||
This->lpFormat->cbSize = 2*sizeof(WORD);
|
||||
((LPG723_ADPCMWAVEFORMAT)This->lpFormat)->cbExtraSize = 0;
|
||||
((LPG723_ADPCMWAVEFORMAT)This->lpFormat)->nAuxBlockSize = 0;
|
||||
break;
|
||||
default:
|
||||
WARN("unsupported Sun audio format %d\n", auhdr.encoding);
|
||||
return AVIERR_UNSUPPORTED;
|
||||
};
|
||||
|
||||
This->lpFormat->nBlockAlign =
|
||||
(This->lpFormat->nChannels * This->lpFormat->wBitsPerSample) / 8;
|
||||
if (This->lpFormat->nBlockAlign == 0 && This->lpFormat->wBitsPerSample < 8)
|
||||
This->lpFormat->nBlockAlign++;
|
||||
This->lpFormat->nAvgBytesPerSec =
|
||||
This->lpFormat->nBlockAlign * This->lpFormat->nSamplesPerSec;
|
||||
|
||||
This->fDirty = 0;
|
||||
|
||||
This->sInfo.fccType = streamtypeAUDIO;
|
||||
This->sInfo.fccHandler = 0;
|
||||
This->sInfo.dwFlags = 0;
|
||||
This->sInfo.wPriority = 0;
|
||||
This->sInfo.wLanguage = 0;
|
||||
This->sInfo.dwInitialFrames = 0;
|
||||
This->sInfo.dwScale = This->lpFormat->nBlockAlign;
|
||||
This->sInfo.dwRate = This->lpFormat->nAvgBytesPerSec;
|
||||
This->sInfo.dwStart = 0;
|
||||
This->sInfo.dwLength =
|
||||
This->ckData.cksize / This->lpFormat->nBlockAlign;
|
||||
This->sInfo.dwSuggestedBufferSize = This->sInfo.dwLength;
|
||||
This->sInfo.dwSampleSize = This->lpFormat->nBlockAlign;
|
||||
|
||||
This->fInfo.dwStreams = 1;
|
||||
This->fInfo.dwScale = 1;
|
||||
This->fInfo.dwRate = This->lpFormat->nSamplesPerSec;
|
||||
This->fInfo.dwLength =
|
||||
MulDiv(This->ckData.cksize, This->lpFormat->nSamplesPerSec,
|
||||
This->lpFormat->nAvgBytesPerSec);
|
||||
|
||||
return AVIERR_OK;
|
||||
}
|
||||
|
||||
static HRESULT AVIFILE_SaveFile(IAVIFileImpl *This)
|
||||
|
|
Loading…
Reference in New Issue