Commit b07c3efd authored by David Reid's avatar David Reid

Improvements to reading and seeking bytes in decoders.

* To read bytes, use ma_decoder_read_bytes().
* To seek bytes, use ma_decoder_seek_bytes().
* The read pointer is now tracked in the ma_decoder object. You can use
  this to move back to a prior position.
parent b9a4f7a1
...@@ -2854,7 +2854,7 @@ typedef enum ...@@ -2854,7 +2854,7 @@ typedef enum
ma_seek_origin_current ma_seek_origin_current
} ma_seek_origin; } ma_seek_origin;
typedef size_t (* ma_decoder_read_proc) (ma_decoder* pDecoder, void* pBufferOut, size_t bytesToRead); // Returns the number of bytes read. typedef size_t (* ma_decoder_read_proc) (ma_decoder* pDecoder, void* pBufferOut, size_t bytesToRead); // Returns the number of bytes read.
typedef ma_bool32 (* ma_decoder_seek_proc) (ma_decoder* pDecoder, int byteOffset, ma_seek_origin origin); typedef ma_bool32 (* ma_decoder_seek_proc) (ma_decoder* pDecoder, int byteOffset, ma_seek_origin origin);
typedef ma_result (* ma_decoder_seek_to_pcm_frame_proc)(ma_decoder* pDecoder, ma_uint64 frameIndex); typedef ma_result (* ma_decoder_seek_to_pcm_frame_proc)(ma_decoder* pDecoder, ma_uint64 frameIndex);
typedef ma_result (* ma_decoder_uninit_proc) (ma_decoder* pDecoder); typedef ma_result (* ma_decoder_uninit_proc) (ma_decoder* pDecoder);
...@@ -2879,6 +2879,7 @@ struct ma_decoder ...@@ -2879,6 +2879,7 @@ struct ma_decoder
ma_decoder_read_proc onRead; ma_decoder_read_proc onRead;
ma_decoder_seek_proc onSeek; ma_decoder_seek_proc onSeek;
void* pUserData; void* pUserData;
ma_uint64 readPointer; /* Used for returning back to a previous position after analysing the stream or whatnot. */
ma_format internalFormat; ma_format internalFormat;
ma_uint32 internalChannels; ma_uint32 internalChannels;
ma_uint32 internalSampleRate; ma_uint32 internalSampleRate;
...@@ -29807,6 +29808,68 @@ ma_uint32 ma_get_bytes_per_sample(ma_format format) ...@@ -29807,6 +29808,68 @@ ma_uint32 ma_get_bytes_per_sample(ma_format format)
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef MA_NO_DECODING #ifndef MA_NO_DECODING
size_t ma_decoder_read_bytes(ma_decoder* pDecoder, void* pBufferOut, size_t bytesToRead)
{
ma_assert(pDecoder != NULL);
ma_assert(pBufferOut != NULL);
size_t bytesRead = pDecoder->onRead(pDecoder, pBufferOut, bytesToRead);
pDecoder->readPointer += bytesRead;
return bytesRead;
}
ma_bool32 ma_decoder_seek_bytes(ma_decoder* pDecoder, int byteOffset, ma_seek_origin origin)
{
ma_assert(pDecoder != NULL);
ma_bool32 wasSuccessful = pDecoder->onSeek(pDecoder, byteOffset, origin);
if (wasSuccessful) {
if (origin == ma_seek_origin_start) {
pDecoder->readPointer = (ma_uint64)byteOffset;
} else {
pDecoder->readPointer += byteOffset;
}
}
return wasSuccessful;
}
ma_bool32 ma_decoder_seek_bytes_64(ma_decoder* pDecoder, ma_uint64 byteOffset, ma_seek_origin origin)
{
ma_assert(pDecoder != NULL);
if (origin == ma_seek_origin_start) {
ma_uint64 bytesToSeekThisIteration = 0x7FFFFFFF;
if (bytesToSeekThisIteration > byteOffset) {
bytesToSeekThisIteration = byteOffset;
}
if (!ma_decoder_seek_bytes(pDecoder, (int)bytesToSeekThisIteration, ma_seek_origin_start)) {
return MA_FALSE;
}
byteOffset -= bytesToSeekThisIteration;
}
/* Getting here means we need to seek relative to the current position. */
while (byteOffset > 0) {
ma_uint64 bytesToSeekThisIteration = 0x7FFFFFFF;
if (bytesToSeekThisIteration > byteOffset) {
bytesToSeekThisIteration = byteOffset;
}
if (!ma_decoder_seek_bytes(pDecoder, (int)bytesToSeekThisIteration, ma_seek_origin_current)) {
return MA_FALSE;
}
byteOffset -= bytesToSeekThisIteration;
}
return MA_TRUE;
}
ma_decoder_config ma_decoder_config_init(ma_format outputFormat, ma_uint32 outputChannels, ma_uint32 outputSampleRate) ma_decoder_config ma_decoder_config_init(ma_format outputFormat, ma_uint32 outputChannels, ma_uint32 outputSampleRate)
{ {
ma_decoder_config config; ma_decoder_config config;
...@@ -29882,18 +29945,16 @@ size_t ma_decoder_internal_on_read__wav(void* pUserData, void* pBufferOut, size_ ...@@ -29882,18 +29945,16 @@ size_t ma_decoder_internal_on_read__wav(void* pUserData, void* pBufferOut, size_
{ {
ma_decoder* pDecoder = (ma_decoder*)pUserData; ma_decoder* pDecoder = (ma_decoder*)pUserData;
ma_assert(pDecoder != NULL); ma_assert(pDecoder != NULL);
ma_assert(pDecoder->onRead != NULL);
return pDecoder->onRead(pDecoder, pBufferOut, bytesToRead); return ma_decoder_read_bytes(pDecoder, pBufferOut, bytesToRead);
} }
drwav_bool32 ma_decoder_internal_on_seek__wav(void* pUserData, int offset, drwav_seek_origin origin) drwav_bool32 ma_decoder_internal_on_seek__wav(void* pUserData, int offset, drwav_seek_origin origin)
{ {
ma_decoder* pDecoder = (ma_decoder*)pUserData; ma_decoder* pDecoder = (ma_decoder*)pUserData;
ma_assert(pDecoder != NULL); ma_assert(pDecoder != NULL);
ma_assert(pDecoder->onSeek != NULL);
return pDecoder->onSeek(pDecoder, offset, (origin == drwav_seek_origin_start) ? ma_seek_origin_start : ma_seek_origin_current); return ma_decoder_seek_bytes(pDecoder, offset, (origin == drwav_seek_origin_start) ? ma_seek_origin_start : ma_seek_origin_current);
} }
ma_uint32 ma_decoder_internal_on_read_pcm_frames__wav(ma_pcm_converter* pDSP, void* pSamplesOut, ma_uint32 frameCount, void* pUserData) ma_uint32 ma_decoder_internal_on_read_pcm_frames__wav(ma_pcm_converter* pDSP, void* pSamplesOut, ma_uint32 frameCount, void* pUserData)
...@@ -30009,18 +30070,16 @@ size_t ma_decoder_internal_on_read__flac(void* pUserData, void* pBufferOut, size ...@@ -30009,18 +30070,16 @@ size_t ma_decoder_internal_on_read__flac(void* pUserData, void* pBufferOut, size
{ {
ma_decoder* pDecoder = (ma_decoder*)pUserData; ma_decoder* pDecoder = (ma_decoder*)pUserData;
ma_assert(pDecoder != NULL); ma_assert(pDecoder != NULL);
ma_assert(pDecoder->onRead != NULL);
return pDecoder->onRead(pDecoder, pBufferOut, bytesToRead); return ma_decoder_read_bytes(pDecoder, pBufferOut, bytesToRead);
} }
drflac_bool32 ma_decoder_internal_on_seek__flac(void* pUserData, int offset, drflac_seek_origin origin) drflac_bool32 ma_decoder_internal_on_seek__flac(void* pUserData, int offset, drflac_seek_origin origin)
{ {
ma_decoder* pDecoder = (ma_decoder*)pUserData; ma_decoder* pDecoder = (ma_decoder*)pUserData;
ma_assert(pDecoder != NULL); ma_assert(pDecoder != NULL);
ma_assert(pDecoder->onSeek != NULL);
return pDecoder->onSeek(pDecoder, offset, (origin == drflac_seek_origin_start) ? ma_seek_origin_start : ma_seek_origin_current); return ma_decoder_seek_bytes(pDecoder, offset, (origin == drflac_seek_origin_start) ? ma_seek_origin_start : ma_seek_origin_current);
} }
ma_uint32 ma_decoder_internal_on_read_pcm_frames__flac(ma_pcm_converter* pDSP, void* pSamplesOut, ma_uint32 frameCount, void* pUserData) ma_uint32 ma_decoder_internal_on_read_pcm_frames__flac(ma_pcm_converter* pDSP, void* pSamplesOut, ma_uint32 frameCount, void* pUserData)
...@@ -30125,8 +30184,6 @@ ma_uint32 ma_vorbis_decoder_read_pcm_frames(ma_vorbis_decoder* pVorbis, ma_decod ...@@ -30125,8 +30184,6 @@ ma_uint32 ma_vorbis_decoder_read_pcm_frames(ma_vorbis_decoder* pVorbis, ma_decod
{ {
ma_assert(pVorbis != NULL); ma_assert(pVorbis != NULL);
ma_assert(pDecoder != NULL); ma_assert(pDecoder != NULL);
ma_assert(pDecoder->onRead != NULL);
ma_assert(pDecoder->onSeek != NULL);
float* pSamplesOutF = (float*)pSamplesOut; float* pSamplesOutF = (float*)pSamplesOut;
...@@ -30184,7 +30241,7 @@ ma_uint32 ma_vorbis_decoder_read_pcm_frames(ma_vorbis_decoder* pVorbis, ma_decod ...@@ -30184,7 +30241,7 @@ ma_uint32 ma_vorbis_decoder_read_pcm_frames(ma_vorbis_decoder* pVorbis, ma_decod
} }
// Fill in a chunk. // Fill in a chunk.
size_t bytesRead = pDecoder->onRead(pDecoder, pVorbis->pData + pVorbis->dataSize, (pVorbis->dataCapacity - pVorbis->dataSize)); size_t bytesRead = ma_decoder_read_bytes(pDecoder, pVorbis->pData + pVorbis->dataSize, (pVorbis->dataCapacity - pVorbis->dataSize));
if (bytesRead == 0) { if (bytesRead == 0) {
return totalFramesRead; // Error reading more data. return totalFramesRead; // Error reading more data.
} }
...@@ -30201,13 +30258,11 @@ ma_result ma_vorbis_decoder_seek_to_pcm_frame(ma_vorbis_decoder* pVorbis, ma_dec ...@@ -30201,13 +30258,11 @@ ma_result ma_vorbis_decoder_seek_to_pcm_frame(ma_vorbis_decoder* pVorbis, ma_dec
{ {
ma_assert(pVorbis != NULL); ma_assert(pVorbis != NULL);
ma_assert(pDecoder != NULL); ma_assert(pDecoder != NULL);
ma_assert(pDecoder->onRead != NULL);
ma_assert(pDecoder->onSeek != NULL);
// This is terribly inefficient because stb_vorbis does not have a good seeking solution with it's push API. Currently this just performs // This is terribly inefficient because stb_vorbis does not have a good seeking solution with it's push API. Currently this just performs
// a full decode right from the start of the stream. Later on I'll need to write a layer that goes through all of the Ogg pages until we // a full decode right from the start of the stream. Later on I'll need to write a layer that goes through all of the Ogg pages until we
// find the one containing the sample we need. Then we know exactly where to seek for stb_vorbis. // find the one containing the sample we need. Then we know exactly where to seek for stb_vorbis.
if (!pDecoder->onSeek(pDecoder, 0, ma_seek_origin_start)) { if (!ma_decoder_seek_bytes(pDecoder, 0, ma_seek_origin_start)) {
return MA_ERROR; return MA_ERROR;
} }
...@@ -30238,8 +30293,6 @@ ma_result ma_vorbis_decoder_seek_to_pcm_frame(ma_vorbis_decoder* pVorbis, ma_dec ...@@ -30238,8 +30293,6 @@ ma_result ma_vorbis_decoder_seek_to_pcm_frame(ma_vorbis_decoder* pVorbis, ma_dec
ma_result ma_decoder_internal_on_seek_to_pcm_frame__vorbis(ma_decoder* pDecoder, ma_uint64 frameIndex) ma_result ma_decoder_internal_on_seek_to_pcm_frame__vorbis(ma_decoder* pDecoder, ma_uint64 frameIndex)
{ {
ma_assert(pDecoder != NULL); ma_assert(pDecoder != NULL);
ma_assert(pDecoder->onRead != NULL);
ma_assert(pDecoder->onSeek != NULL);
ma_vorbis_decoder* pVorbis = (ma_vorbis_decoder*)pDecoder->pInternalDecoder; ma_vorbis_decoder* pVorbis = (ma_vorbis_decoder*)pDecoder->pInternalDecoder;
ma_assert(pVorbis != NULL); ma_assert(pVorbis != NULL);
...@@ -30266,8 +30319,6 @@ ma_uint32 ma_decoder_internal_on_read_pcm_frames__vorbis(ma_pcm_converter* pDSP, ...@@ -30266,8 +30319,6 @@ ma_uint32 ma_decoder_internal_on_read_pcm_frames__vorbis(ma_pcm_converter* pDSP,
ma_decoder* pDecoder = (ma_decoder*)pUserData; ma_decoder* pDecoder = (ma_decoder*)pUserData;
ma_assert(pDecoder != NULL); ma_assert(pDecoder != NULL);
ma_assert(pDecoder->internalFormat == ma_format_f32); ma_assert(pDecoder->internalFormat == ma_format_f32);
ma_assert(pDecoder->onRead != NULL);
ma_assert(pDecoder->onSeek != NULL);
ma_vorbis_decoder* pVorbis = (ma_vorbis_decoder*)pDecoder->pInternalDecoder; ma_vorbis_decoder* pVorbis = (ma_vorbis_decoder*)pDecoder->pInternalDecoder;
ma_assert(pVorbis != NULL); ma_assert(pVorbis != NULL);
...@@ -30279,8 +30330,6 @@ ma_result ma_decoder_init_vorbis__internal(const ma_decoder_config* pConfig, ma_ ...@@ -30279,8 +30330,6 @@ ma_result ma_decoder_init_vorbis__internal(const ma_decoder_config* pConfig, ma_
{ {
ma_assert(pConfig != NULL); ma_assert(pConfig != NULL);
ma_assert(pDecoder != NULL); ma_assert(pDecoder != NULL);
ma_assert(pDecoder->onRead != NULL);
ma_assert(pDecoder->onSeek != NULL);
stb_vorbis* pInternalVorbis = NULL; stb_vorbis* pInternalVorbis = NULL;
...@@ -30301,7 +30350,7 @@ ma_result ma_decoder_init_vorbis__internal(const ma_decoder_config* pConfig, ma_ ...@@ -30301,7 +30350,7 @@ ma_result ma_decoder_init_vorbis__internal(const ma_decoder_config* pConfig, ma_
pData = pNewData; pData = pNewData;
// Fill in a chunk. // Fill in a chunk.
size_t bytesRead = pDecoder->onRead(pDecoder, pData + dataSize, (dataCapacity - dataSize)); size_t bytesRead = ma_decoder_read_bytes(pDecoder, pData + dataSize, (dataCapacity - dataSize));
if (bytesRead == 0) { if (bytesRead == 0) {
return MA_ERROR; return MA_ERROR;
} }
...@@ -30388,18 +30437,16 @@ size_t ma_decoder_internal_on_read__mp3(void* pUserData, void* pBufferOut, size_ ...@@ -30388,18 +30437,16 @@ size_t ma_decoder_internal_on_read__mp3(void* pUserData, void* pBufferOut, size_
{ {
ma_decoder* pDecoder = (ma_decoder*)pUserData; ma_decoder* pDecoder = (ma_decoder*)pUserData;
ma_assert(pDecoder != NULL); ma_assert(pDecoder != NULL);
ma_assert(pDecoder->onRead != NULL);
return pDecoder->onRead(pDecoder, pBufferOut, bytesToRead); return ma_decoder_read_bytes(pDecoder, pBufferOut, bytesToRead);
} }
drmp3_bool32 ma_decoder_internal_on_seek__mp3(void* pUserData, int offset, drmp3_seek_origin origin) drmp3_bool32 ma_decoder_internal_on_seek__mp3(void* pUserData, int offset, drmp3_seek_origin origin)
{ {
ma_decoder* pDecoder = (ma_decoder*)pUserData; ma_decoder* pDecoder = (ma_decoder*)pUserData;
ma_assert(pDecoder != NULL); ma_assert(pDecoder != NULL);
ma_assert(pDecoder->onSeek != NULL);
return pDecoder->onSeek(pDecoder, offset, (origin == drmp3_seek_origin_start) ? ma_seek_origin_start : ma_seek_origin_current); return ma_decoder_seek_bytes(pDecoder, offset, (origin == drmp3_seek_origin_start) ? ma_seek_origin_start : ma_seek_origin_current);
} }
ma_uint32 ma_decoder_internal_on_read_pcm_frames__mp3(ma_pcm_converter* pDSP, void* pSamplesOut, ma_uint32 frameCount, void* pUserData) ma_uint32 ma_decoder_internal_on_read_pcm_frames__mp3(ma_pcm_converter* pDSP, void* pSamplesOut, ma_uint32 frameCount, void* pUserData)
...@@ -30494,7 +30541,7 @@ ma_uint32 ma_decoder_internal_on_read_pcm_frames__raw(ma_pcm_converter* pDSP, vo ...@@ -30494,7 +30541,7 @@ ma_uint32 ma_decoder_internal_on_read_pcm_frames__raw(ma_pcm_converter* pDSP, vo
// For raw decoding we just read directly from the decoder's callbacks. // For raw decoding we just read directly from the decoder's callbacks.
ma_uint32 bpf = ma_get_bytes_per_frame(pDecoder->internalFormat, pDecoder->internalChannels); ma_uint32 bpf = ma_get_bytes_per_frame(pDecoder->internalFormat, pDecoder->internalChannels);
return (ma_uint32)pDecoder->onRead(pDecoder, pSamplesOut, frameCount * bpf) / bpf; return (ma_uint32)ma_decoder_read_bytes(pDecoder, pSamplesOut, frameCount * bpf) / bpf;
} }
ma_result ma_decoder_internal_on_seek_to_pcm_frame__raw(ma_decoder* pDecoder, ma_uint64 frameIndex) ma_result ma_decoder_internal_on_seek_to_pcm_frame__raw(ma_decoder* pDecoder, ma_uint64 frameIndex)
...@@ -30511,10 +30558,10 @@ ma_result ma_decoder_internal_on_seek_to_pcm_frame__raw(ma_decoder* pDecoder, ma ...@@ -30511,10 +30558,10 @@ ma_result ma_decoder_internal_on_seek_to_pcm_frame__raw(ma_decoder* pDecoder, ma
ma_uint64 totalBytesToSeek = frameIndex * ma_get_bytes_per_frame(pDecoder->internalFormat, pDecoder->internalChannels); ma_uint64 totalBytesToSeek = frameIndex * ma_get_bytes_per_frame(pDecoder->internalFormat, pDecoder->internalChannels);
if (totalBytesToSeek < 0x7FFFFFFF) { if (totalBytesToSeek < 0x7FFFFFFF) {
// Simple case. // Simple case.
result = pDecoder->onSeek(pDecoder, (int)(frameIndex * ma_get_bytes_per_frame(pDecoder->internalFormat, pDecoder->internalChannels)), ma_seek_origin_start); result = ma_decoder_seek_bytes(pDecoder, (int)(frameIndex * ma_get_bytes_per_frame(pDecoder->internalFormat, pDecoder->internalChannels)), ma_seek_origin_start);
} else { } else {
// Complex case. Start by doing a seek relative to the start. Then keep looping using offset seeking. // Complex case. Start by doing a seek relative to the start. Then keep looping using offset seeking.
result = pDecoder->onSeek(pDecoder, 0x7FFFFFFF, ma_seek_origin_start); result = ma_decoder_seek_bytes(pDecoder, 0x7FFFFFFF, ma_seek_origin_start);
if (result == MA_TRUE) { if (result == MA_TRUE) {
totalBytesToSeek -= 0x7FFFFFFF; totalBytesToSeek -= 0x7FFFFFFF;
...@@ -30524,7 +30571,7 @@ ma_result ma_decoder_internal_on_seek_to_pcm_frame__raw(ma_decoder* pDecoder, ma ...@@ -30524,7 +30571,7 @@ ma_result ma_decoder_internal_on_seek_to_pcm_frame__raw(ma_decoder* pDecoder, ma
bytesToSeekThisIteration = 0x7FFFFFFF; bytesToSeekThisIteration = 0x7FFFFFFF;
} }
result = pDecoder->onSeek(pDecoder, (int)bytesToSeekThisIteration, ma_seek_origin_current); result = ma_decoder_seek_bytes(pDecoder, (int)bytesToSeekThisIteration, ma_seek_origin_current);
if (result != MA_TRUE) { if (result != MA_TRUE) {
break; break;
} }
...@@ -295,12 +295,12 @@ ...@@ -295,12 +295,12 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="..\examples\simple_playback.c"> <ClCompile Include="..\examples\simple_playback.c">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">false</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">false</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="..\research\tests\ma_resampler_test_0.c"> <ClCompile Include="..\research\tests\ma_resampler_test_0.c">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
...@@ -367,12 +367,12 @@ ...@@ -367,12 +367,12 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="ma_test_0.cpp"> <ClCompile Include="ma_test_0.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">false</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">false</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile> </ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment