mirror of
https://github.com/WinampDesktop/winamp.git
synced 2025-06-15 22:55:46 -04:00
Basic CD image loading
This commit is contained in:
119
src/common/cd_image.cpp
Normal file
119
src/common/cd_image.cpp
Normal file
@ -0,0 +1,119 @@
|
||||
#include "cd_image.h"
|
||||
#include "YBaseLib/ByteStream.h"
|
||||
#include "YBaseLib/Log.h"
|
||||
Log_SetChannel(CDImage);
|
||||
|
||||
CDImage::CDImage() = default;
|
||||
|
||||
CDImage::~CDImage()
|
||||
{
|
||||
if (m_data_file)
|
||||
m_data_file->Release();
|
||||
}
|
||||
|
||||
constexpr u64 CDImage::MSFToLBA(u32 minute, u32 second, u32 frame)
|
||||
{
|
||||
return ZeroExtend64(minute) * FRAMES_PER_MINUTE + ZeroExtend64(second) * FRAMES_PER_SECOND + ZeroExtend64(frame);
|
||||
}
|
||||
|
||||
constexpr void CDImage::LBAToMSF(u64 lba, u32* minute, u32* second, u32* frame)
|
||||
{
|
||||
const u32 offset = lba % FRAMES_PER_MINUTE;
|
||||
*minute = Truncate32(lba / FRAMES_PER_MINUTE);
|
||||
*second = Truncate32(offset / FRAMES_PER_SECOND);
|
||||
*frame = Truncate32(offset % FRAMES_PER_SECOND);
|
||||
}
|
||||
|
||||
bool CDImage::Open(const char* path)
|
||||
{
|
||||
Assert(!m_data_file);
|
||||
|
||||
if (!ByteStream_OpenFileStream(path, BYTESTREAM_OPEN_READ | BYTESTREAM_OPEN_SEEKABLE, &m_data_file))
|
||||
{
|
||||
Log_ErrorPrintf("Failed to open '%s'", path);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_lba_count = m_data_file->GetSize() / RAW_SECTOR_SIZE;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDImage::Seek(u64 lba)
|
||||
{
|
||||
if (lba >= m_lba_count)
|
||||
return false;
|
||||
|
||||
if (!m_data_file->SeekAbsolute(lba * RAW_SECTOR_SIZE))
|
||||
return false;
|
||||
|
||||
m_current_lba = lba;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDImage::Seek(u32 minute, u32 second, u32 frame)
|
||||
{
|
||||
return Seek(MSFToLBA(minute, second, frame));
|
||||
}
|
||||
|
||||
u32 CDImage::Read(ReadMode read_mode, u64 lba, u32 sector_count, void* buffer)
|
||||
{
|
||||
if (!Seek(lba))
|
||||
return false;
|
||||
|
||||
return Read(read_mode, sector_count, buffer);
|
||||
}
|
||||
|
||||
u32 CDImage::Read(ReadMode read_mode, u32 minute, u32 second, u32 frame, u32 sector_count, void* buffer)
|
||||
{
|
||||
if (!Seek(minute, second, frame))
|
||||
return false;
|
||||
|
||||
return Read(read_mode, sector_count, buffer);
|
||||
}
|
||||
|
||||
u32 CDImage::Read(ReadMode read_mode, u32 sector_count, void* buffer)
|
||||
{
|
||||
char* buffer_ptr = static_cast<char*>(buffer);
|
||||
u32 sectors_read = 0;
|
||||
for (; sectors_read < sector_count; sectors_read++)
|
||||
{
|
||||
if (m_current_lba == m_lba_count)
|
||||
break;
|
||||
|
||||
// get raw sector
|
||||
char raw_sector[RAW_SECTOR_SIZE];
|
||||
if (!m_data_file->Read2(raw_sector, RAW_SECTOR_SIZE))
|
||||
{
|
||||
Log_ErrorPrintf("Read of LBA %llu failed", m_current_lba);
|
||||
m_data_file->SeekAbsolute(m_current_lba * RAW_SECTOR_SIZE);
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (read_mode)
|
||||
{
|
||||
case ReadMode::DataOnly:
|
||||
std::memcpy(buffer_ptr, raw_sector + SECTOR_SYNC_SIZE, DATA_SECTOR_SIZE);
|
||||
buffer_ptr += DATA_SECTOR_SIZE;
|
||||
break;
|
||||
|
||||
case ReadMode::RawNoSync:
|
||||
std::memcpy(buffer_ptr, raw_sector + SECTOR_SYNC_SIZE, RAW_SECTOR_SIZE - SECTOR_SYNC_SIZE);
|
||||
buffer_ptr += RAW_SECTOR_SIZE - SECTOR_SYNC_SIZE;
|
||||
break;
|
||||
|
||||
case ReadMode::RawSector:
|
||||
std::memcpy(buffer_ptr, raw_sector, RAW_SECTOR_SIZE);
|
||||
buffer_ptr += RAW_SECTOR_SIZE;
|
||||
break;
|
||||
|
||||
default:
|
||||
UnreachableCode();
|
||||
break;
|
||||
}
|
||||
|
||||
m_current_lba++;
|
||||
sectors_read++;
|
||||
}
|
||||
|
||||
return sectors_read;
|
||||
}
|
59
src/common/cd_image.h
Normal file
59
src/common/cd_image.h
Normal file
@ -0,0 +1,59 @@
|
||||
#pragma once
|
||||
#include "types.h"
|
||||
|
||||
class ByteStream;
|
||||
|
||||
class CDImage
|
||||
{
|
||||
public:
|
||||
CDImage();
|
||||
~CDImage();
|
||||
|
||||
enum class ReadMode : u32
|
||||
{
|
||||
DataOnly, // 2048 bytes per sector.
|
||||
RawSector, // 2352 bytes per sector.
|
||||
RawNoSync, // 2340 bytes per sector.
|
||||
};
|
||||
|
||||
// Conversion helpers.
|
||||
static constexpr u64 MSFToLBA(u32 minute, u32 second, u32 frame);
|
||||
static constexpr void LBAToMSF(u64 lba, u32* minute, u32* second, u32* frame);
|
||||
|
||||
// Accessors.
|
||||
u64 GetCurrentLBA() const { return m_current_lba; }
|
||||
u64 GetLBACount() const { return m_lba_count; }
|
||||
|
||||
bool Open(const char* path);
|
||||
|
||||
// Seek to data LBA.
|
||||
bool Seek(u64 lba);
|
||||
|
||||
// Seek to audio timestamp (MSF).
|
||||
bool Seek(u32 minute, u32 second, u32 frame);
|
||||
|
||||
// Seek and read at the same time.
|
||||
u32 Read(ReadMode read_mode, u64 lba, u32 sector_count, void* buffer);
|
||||
u32 Read(ReadMode read_mode, u32 minute, u32 second, u32 frame, u32 sector_count, void* buffer);
|
||||
|
||||
// Read from the current LBA. Returns the number of sectors read.
|
||||
u32 Read(ReadMode read_mode, u32 sector_count, void* buffer);
|
||||
|
||||
private:
|
||||
enum : u32
|
||||
{
|
||||
RAW_SECTOR_SIZE = 2352,
|
||||
DATA_SECTOR_SIZE = 2048,
|
||||
SECTOR_SYNC_SIZE = 12,
|
||||
FRAMES_PER_SECOND = 75, // "sectors"
|
||||
SECONDS_PER_MINUTE = 60,
|
||||
FRAMES_PER_MINUTE = FRAMES_PER_SECOND * SECONDS_PER_MINUTE,
|
||||
};
|
||||
|
||||
// TODO: Multiple data files from cue sheet
|
||||
ByteStream* m_data_file = nullptr;
|
||||
|
||||
// Current LBA/total LBAs.
|
||||
u64 m_current_lba = 0;
|
||||
u64 m_lba_count = 0;
|
||||
};
|
@ -37,6 +37,7 @@
|
||||
<ItemGroup>
|
||||
<ClInclude Include="audio.h" />
|
||||
<ClInclude Include="bitfield.h" />
|
||||
<ClInclude Include="cd_image.h" />
|
||||
<ClInclude Include="display.h" />
|
||||
<ClInclude Include="display_renderer_d3d.h" />
|
||||
<ClInclude Include="display_renderer.h" />
|
||||
@ -57,6 +58,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="audio.cpp" />
|
||||
<ClCompile Include="cd_image.cpp" />
|
||||
<ClCompile Include="display.cpp" />
|
||||
<ClCompile Include="display_renderer_d3d.cpp" />
|
||||
<ClCompile Include="display_renderer.cpp" />
|
||||
|
@ -20,6 +20,7 @@
|
||||
<ClInclude Include="gl_program.h" />
|
||||
<ClInclude Include="gl_texture.h" />
|
||||
<ClInclude Include="fifo_queue.h" />
|
||||
<ClInclude Include="cd_image.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="hdd_image.cpp" />
|
||||
@ -36,6 +37,7 @@
|
||||
<ClCompile Include="state_wrapper.cpp" />
|
||||
<ClCompile Include="gl_program.cpp" />
|
||||
<ClCompile Include="gl_texture.cpp" />
|
||||
<ClCompile Include="cd_image.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="bitfield.natvis" />
|
||||
|
Reference in New Issue
Block a user