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;
}
示例#2
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;
}