int _seek_func(void *datasource, ogg_int64_t offset, int whence) { MkInterfaceForDataReading* drInterface = reinterpret_cast<MkInterfaceForDataReading*>(datasource); switch (whence) { case SEEK_SET: drInterface->SetCurrentPosition(static_cast<unsigned int>(offset)); break; case SEEK_CUR: drInterface->SetCurrentPosition(static_cast<unsigned int>(offset) + drInterface->GetCurrentPosition()); break; case SEEK_END: drInterface->SetCurrentPosition(drInterface->GetEndPosition() - static_cast<unsigned int>(offset)); break; } return 0; }
virtual bool SetUp(MkDataNode& sharingNode) { // [ data 형태 정의 ] //------------------------------------------------------------------------------------------------// // int a; // float b; // MkVec3 c; // wchar_t d[64]; //------------------------------------------------------------------------------------------------// // srcArray 생성 MkInterfaceForDataWriting dwInterface; dwInterface.SetInputSize(ePDT_Int, SIZE_COUNT); dwInterface.SetInputSize(ePDT_Float, SIZE_COUNT); dwInterface.SetInputSize(ePDT_Vec3, SIZE_COUNT); dwInterface.SetInputSize(ePDT_Str, SIZE_COUNT); dwInterface.UpdateInputSize(); for (int i=0; i<SIZE_COUNT; ++i) { float f = static_cast<float>(i); dwInterface.Write(static_cast<int>(i)); dwInterface.Write(static_cast<float>(f * -10.f)); dwInterface.Write(MkVec3(f, f * -2.f, f * 3.f)); dwInterface.Write(MkStr(L"잘생겨서 죄송요~")); } MkByteArray srcArray; dwInterface.Flush(srcArray); dwInterface.Clear(); // srcArray -> 파일로 출력 MkInterfaceForFileWriting fwInterface; fwInterface.SetUp(L"test.data", true, true); fwInterface.Write(srcArray, MkArraySection(0)); fwInterface.Clear(); srcArray.Clear(); // 파일을 destBuffer에 읽음 MkByteArray destBuffer; MkInterfaceForFileReading frInterface; frInterface.SetUp(L"test.data"); frInterface.Read(destBuffer, MkArraySection(0)); frInterface.Clear(); MK_DEV_PANEL.MsgToLog(MkStr::EMPTY); // 빈 칸 하나 넣고, // 읽어들인 결과 출력. 첫번째와 마지막 unit 대상 MkInterfaceForDataReading drInterface; drInterface.SetUp(destBuffer, 0); for (int i=0; i<SIZE_COUNT; ++i) { int a = 0; drInterface.Read(a); float b = 0.f; drInterface.Read(b); MkVec3 c = MkVec3::Zero; drInterface.Read(c); MkStr d; drInterface.Read(d); if (i == 0) { MK_DEV_PANEL.MsgToLog(L"[ First unit ]"); MK_DEV_PANEL.MsgToLog(L" a : " + MkStr(a)); MK_DEV_PANEL.MsgToLog(L" b : " + MkStr(b)); MK_DEV_PANEL.MsgToLog(L" c : " + MkStr(c)); MK_DEV_PANEL.MsgToLog(L" d : " + MkStr(d)); } else if (i == (SIZE_COUNT - 1)) { MK_DEV_PANEL.MsgToLog(L"[ Last unit ]"); MK_DEV_PANEL.MsgToLog(L" a : " + MkStr(a)); MK_DEV_PANEL.MsgToLog(L" b : " + MkStr(b)); MK_DEV_PANEL.MsgToLog(L" c : " + MkStr(c)); MK_DEV_PANEL.MsgToLog(L" d : " + MkStr(d)); } } destBuffer.Clear(); // 출력 폴더 열기 MkPathName::GetRootDirectory().OpenDirectoryInExplorer(); return true; }
bool MkSoundBuffer::_CreateBufferFromOggFile(LPDIRECTSOUND directSound, const MkByteArray& srcData) { OggVorbis_File vorbisFile; ::ZeroMemory(&vorbisFile, sizeof(OggVorbis_File)); do { MkInterfaceForDataReading drInterface; if (!drInterface.SetUp(srcData, 0)) break; // vorbis file 오픈 ov_callbacks ogg_callbacks = { _read_func, _seek_func, _close_func, _tell_func }; if (ov_open_callbacks(reinterpret_cast<void*>(&drInterface), &vorbisFile, NULL, 0, ogg_callbacks) != 0) break; // 구조 정보 vorbis_info* vorbisInfo = ov_info(&vorbisFile, -1); if (vorbisInfo == NULL) break; // 버퍼 확보 int dataSize = vorbisInfo->channels * 16 / 8 * static_cast<int>(ov_pcm_total(&vorbisFile, -1)); if (dataSize <= 0) break; MkByteArray dataBuffer; dataBuffer.Fill(static_cast<unsigned int>(dataSize)); // PCM 블록 읽으며 디코딩 int bitstream, readSize = 0, writeSize = 0; while (true) { writeSize = ov_read(&vorbisFile, reinterpret_cast<char*>(dataBuffer.GetPtr()) + readSize, dataSize - readSize, 0, 2, 1, &bitstream); if(writeSize == 0) // EOF break; if ((dataSize - readSize) >= 0) // continue { readSize += writeSize; } else // 디코딩 실패 { writeSize = -1; break; } } if (writeSize < 0) break; // wave 정보 세팅 WAVEFORMATEX waveFormatEx; waveFormatEx.wFormatTag = WAVE_FORMAT_PCM; waveFormatEx.nChannels = vorbisInfo->channels; waveFormatEx.nSamplesPerSec = vorbisInfo->rate; waveFormatEx.nAvgBytesPerSec = vorbisInfo->channels * vorbisInfo->rate * 16 / 8; // 채널 * 주파수 * 진폭 / 8(bit>byte) waveFormatEx.nBlockAlign = vorbisInfo->channels * 16 / 8; waveFormatEx.wBitsPerSample = 16; waveFormatEx.cbSize = 0; // 사운드 버퍼 생성 후 데이터 복사 m_SoundBuffer = _CreateSoundBuffer(directSound, waveFormatEx, dataBuffer); } while (false); ov_clear(&vorbisFile); return (m_SoundBuffer != NULL); }
long _tell_func(void *datasource) { MkInterfaceForDataReading* drInterface = reinterpret_cast<MkInterfaceForDataReading*>(datasource); return drInterface->GetCurrentPosition(); }
// vorbis call back size_t _read_func(void *ptr, size_t size, size_t nmemb, void *datasource) { MkInterfaceForDataReading* drInterface = reinterpret_cast<MkInterfaceForDataReading*>(datasource); size_t copySize = GetMin<size_t>(size * nmemb, drInterface->GetEndPosition() - drInterface->GetCurrentPosition()); return drInterface->Read(reinterpret_cast<unsigned char*>(ptr), copySize) ? copySize : 0; }