#include "AudioFile.h"
AudioFile::AudioFile(String^ filename)
: m_file(NULL), m_filename(filename), m_soundFormat(nullptr), m_soundData(nullptr)
{
}
AudioFile::~AudioFile()
{
if (NULL != m_file)
{
CloseHandle(m_file);
m_file = NULL;
}
}
Platform::Array<byte>^ AudioFile::getSoundData()
{
GetData();
return m_soundData;
}
Platform::Array<byte>^ AudioFile::getSoundFormat()
{
GetData();
return m_soundFormat;
}
void AudioFile::GetData()
{
if (NULL == m_file && m_filename != nullptr)
{
try
{
if (0 == openFile(m_filename))
{
uint64 fileSize = getFileSize();
if (fileSize > 0)
{
// Locate, read and validate the RIFF chunk
uint64 riffLoc = FindChunk(FOURCC_RIFF_TAG, 0, fileSize);
// Read beyond the riff header.
ChunkHeader chunkHeader;
ReadHeader(riffLoc, chunkHeader);
uint32 tag = 0;
Platform::Array<byte>^ riffData = Read(sizeof(tag));
tag = *reinterpret_cast<uint32*>(riffData->Data);
if (tag != FOURCC_WAVE_FILE_TAG)
{
// Only support .wav files
throw ref new Platform::FailureException();
}
uint64 riffChildrenStart = riffLoc + sizeof(chunkHeader) + sizeof(tag);
uint64 riffChildrenEnd = riffLoc + sizeof(chunkHeader) + chunkHeader.size;
// Find, read and validate the format chunk (a child within the RIFF chunk)
uint64 formatLoc = FindChunk(FOURCC_FORMAT_TAG, riffChildrenStart, riffChildrenEnd);
ReadHeader(formatLoc, chunkHeader);
m_soundFormat = Read(chunkHeader.size);
WAVEFORMATEX* format = reinterpret_cast<WAVEFORMATEX*>(m_soundFormat->Data);
if (format->wFormatTag != WAVE_FORMAT_PCM
&& format->wFormatTag != WAVE_FORMAT_ADPCM)
{
// This is not PCM or ADPCM, which is all we support
throw ref new Platform::FailureException();
}
// Locate, the PCM data in the data chunk
uint64 dataChunkStart = FindChunk(FOURCC_DATA_TAG, riffChildrenStart, riffChildrenEnd);
ReadHeader(dataChunkStart, chunkHeader);
// Now read the PCM data and setup the buffer
m_soundData = Read(chunkHeader.size);
}
}
}
catch (Platform::Exception^ e)
{
CloseHandle(m_file);
m_file = NULL;
}
}
}
int AudioFile::openFile(String^ filename)
{
Platform::String^ fullPath = Windows::ApplicationModel::Package::Current->InstalledLocation->Path;
fullPath += filename;
m_file = ::CreateFile2(
fullPath->Data(),
GENERIC_READ,
FILE_SHARE_READ,
OPEN_EXISTING,
nullptr
);
if (m_file == INVALID_HANDLE_VALUE)
{
return -1;
}
return 0;
}
uint64 AudioFile::getFileSize()
{
FILE_STANDARD_INFO fileStandardInfo = { 0 };
BOOL result = ::GetFileInformationByHandleEx(
m_file,
FileStandardInfo,
&fileStandardInfo,
sizeof(fileStandardInfo)
);
if ((result == 0) || (fileStandardInfo.AllocationSize.QuadPart < 0))
{
return 0;
}
return fileStandardInfo.AllocationSize.QuadPart;
}
void AudioFile::SeekAbsolute(uint64 position)
{
if (position < 0)
{
throw ref new Platform::FailureException();
}
LARGE_INTEGER pos;
pos.QuadPart = position;
BOOL result = ::SetFilePointerEx(m_file, pos, nullptr, FILE_BEGIN);
if (result == 0)
{
throw ref new Platform::FailureException();
}
}
void AudioFile::SeekRelative(int64 offset)
{
LARGE_INTEGER position;
position.QuadPart = offset;
BOOL result = ::SetFilePointerEx(m_file, position, nullptr, FILE_CURRENT);
if (result == 0)
{
throw ref new Platform::FailureException();
}
}
Platform::Array<byte>^ AudioFile::Read(_In_ size_t bytesToRead)
{
Platform::Array<byte>^ fileData = ref new Platform::Array<byte>(static_cast<unsigned int>(bytesToRead));
if (!ReadFile(
m_file,
fileData->Data,
fileData->Length,
nullptr,
nullptr
))
{
throw ref new Platform::FailureException();
}
return fileData;
}
uint64 AudioFile::FindChunk(uint32 tag, uint64 startLoc, uint64 endLoc)
{
// Move to start of search
SeekAbsolute(startLoc);
uint64 newLoc = startLoc;
while (endLoc > (newLoc + sizeof(ChunkHeader)))
{
Platform::Array<byte>^ headerBytes = Read(sizeof(ChunkHeader));
ChunkHeader* header = reinterpret_cast<ChunkHeader*>(headerBytes->Data);
if (header->tag == tag)
{
// Found the requested tag
return newLoc;
}
SeekRelative(static_cast<int64>(header->size));
newLoc += header->size + sizeof(*header);
}
return -1;
}
void AudioFile::ReadHeader(uint64 loc, ChunkHeader& header)
{
// Move to read location
SeekAbsolute(loc);
Platform::Array<byte>^ headerBytes = Read(sizeof(ChunkHeader));
header = *reinterpret_cast<ChunkHeader*>(headerBytes->Data);
}
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
AudioPlay.rar (8个子文件)
AudioFile.cpp 6KB
Player.h 2KB
AudioPlay.cpp 5KB
paldispatcher.cpp 243B
AudioPlay.h 455B
paldispatcher.h 418B
Player.cpp 4KB
AudioFile.h 1KB
共 8 条
- 1
资源评论
- wjkl13142013-07-15代码不适用
Tim_包
- 粉丝: 67
- 资源: 8
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功