mirror of
https://github.com/jorio/Pomme.git
synced 2024-12-27 06:29:18 +00:00
Remove resource dumping functionality - will be moved to a separate tool
This commit is contained in:
parent
644ade79c3
commit
664c738817
@ -27,8 +27,6 @@ static std::vector<ResourceFork> rezSearchStack;
|
|||||||
|
|
||||||
static int rezSearchStackIndex = 0;
|
static int rezSearchStackIndex = 0;
|
||||||
|
|
||||||
static fs::path rezDumpHostDestinationPath = "";
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Internal
|
// Internal
|
||||||
|
|
||||||
@ -45,76 +43,6 @@ static ResourceFork& GetCurRF()
|
|||||||
return rezSearchStack[rezSearchStackIndex];
|
return rezSearchStack[rezSearchStackIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
static void PrintStack(const char* msg) {
|
|
||||||
LOG << "------ RESOURCE SEARCH STACK " << msg << " -------\n";
|
|
||||||
for (int i = int(rezSearchStack.size() - 1); i >= 0; i--) {
|
|
||||||
LOG << (rezSearchStackIndex == i? " =====> " : " ")
|
|
||||||
<< " StackPos=" << i << " "
|
|
||||||
<< " RefNum=" << rezSearchStack[i].fileRefNum << " "
|
|
||||||
// << Pomme::Files::GetHostFilename(rezSearchStack[i].fileRefNum)
|
|
||||||
<< "\n";
|
|
||||||
}
|
|
||||||
LOG << "------------------------------------\n";
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void DumpResource(const ResourceMetadata& meta)
|
|
||||||
{
|
|
||||||
const FSSpec& spec = Pomme::Files::GetSpec(meta.forkRefNum);
|
|
||||||
|
|
||||||
Handle handle = NewHandle(meta.size);
|
|
||||||
auto& fork = Pomme::Files::GetStream(meta.forkRefNum);
|
|
||||||
fork.seekg(meta.dataOffset, std::ios::beg);
|
|
||||||
fork.read(*handle, meta.size);
|
|
||||||
|
|
||||||
fs::path outPath;
|
|
||||||
outPath = rezDumpHostDestinationPath;
|
|
||||||
outPath /= spec.cName;
|
|
||||||
outPath /= Pomme::FourCCString(meta.type, '_');
|
|
||||||
fs::create_directories(outPath);
|
|
||||||
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << meta.id;
|
|
||||||
if (!meta.name.empty())
|
|
||||||
{
|
|
||||||
ss << "-";
|
|
||||||
for (auto c: meta.name)
|
|
||||||
ss << (char)(isalnum(c)? c: '_');
|
|
||||||
}
|
|
||||||
outPath /= ss.str();
|
|
||||||
outPath += "." + Pomme::FourCCString(meta.type, '_');
|
|
||||||
|
|
||||||
std::ofstream dump(outPath, std::ios::binary);
|
|
||||||
|
|
||||||
// Add a 512-byte blank header to PICTs so tools such as ImageMagick or Preview.app will display them
|
|
||||||
if (meta.type == 'PICT')
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 512; i++)
|
|
||||||
dump.put(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
dump.write(*handle, meta.size);
|
|
||||||
dump.close();
|
|
||||||
std::cout << "wrote " << outPath << "\n";
|
|
||||||
|
|
||||||
#if _DEBUG && !POMME_NO_SOUND
|
|
||||||
// Dump sounds as AIFF as well
|
|
||||||
if (meta.type == 'snd ')
|
|
||||||
{
|
|
||||||
outPath.replace_extension(".aiff");
|
|
||||||
std::ofstream aiff(outPath, std::ios::binary);
|
|
||||||
Pomme::Sound::DumpSoundResourceToAIFF(handle, aiff, meta.name);
|
|
||||||
aiff.close();
|
|
||||||
|
|
||||||
std::cout << "wrote " << outPath << "\n";
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
DisposeHandle(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Resource file management
|
// Resource file management
|
||||||
|
|
||||||
@ -214,10 +142,6 @@ short FSpOpenResFile(const FSSpec* spec, char permission)
|
|||||||
resMetadata.size = size;
|
resMetadata.size = size;
|
||||||
resMetadata.name = name;
|
resMetadata.name = name;
|
||||||
GetCurRF().resourceMap[resType][resID] = resMetadata;
|
GetCurRF().resourceMap[resType][resID] = resMetadata;
|
||||||
|
|
||||||
// Dump resource to file (if user called Pomme_StartDumpingResource)
|
|
||||||
if (!rezDumpHostDestinationPath.empty())
|
|
||||||
DumpResource(resMetadata);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -451,15 +375,3 @@ long SizeResource(Handle theResource)
|
|||||||
{
|
{
|
||||||
return GetResourceSizeOnDisk(theResource);
|
return GetResourceSizeOnDisk(theResource);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pomme_StartDumpingResources(const char* hostDestinationPath)
|
|
||||||
{
|
|
||||||
if (hostDestinationPath)
|
|
||||||
{
|
|
||||||
rezDumpHostDestinationPath = hostDestinationPath;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rezDumpHostDestinationPath.clear();
|
|
||||||
}
|
|
||||||
}
|
|
@ -130,11 +130,6 @@ long GetResourceSizeOnDisk(Handle);
|
|||||||
|
|
||||||
long SizeResource(Handle);
|
long SizeResource(Handle);
|
||||||
|
|
||||||
// After calling this function, Pomme will dump all resources to separate files
|
|
||||||
// whenever a new resource fork is opened.
|
|
||||||
// Pass in NULL to stop dumping resources.
|
|
||||||
void Pomme_StartDumpingResources(const char* hostDestinationPath);
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// QuickDraw 2D: Errors
|
// QuickDraw 2D: Errors
|
||||||
|
|
||||||
|
@ -16,8 +16,6 @@ namespace Pomme::Sound
|
|||||||
|
|
||||||
void ReadAIFF(std::istream& input, cmixer::WavStream& output);
|
void ReadAIFF(std::istream& input, cmixer::WavStream& output);
|
||||||
|
|
||||||
void DumpSoundResourceToAIFF(Handle input, std::ostream& output, const std::string& resourceName);
|
|
||||||
|
|
||||||
class Codec
|
class Codec
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -924,139 +924,3 @@ std::unique_ptr<Pomme::Sound::Codec> Pomme::Sound::GetCodec(uint32_t fourCC)
|
|||||||
throw std::runtime_error("Unknown audio codec: " + Pomme::FourCCString(fourCC));
|
throw std::runtime_error("Unknown audio codec: " + Pomme::FourCCString(fourCC));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Dump 'snd ' resource to AIFF
|
|
||||||
|
|
||||||
void Pomme::Sound::DumpSoundResourceToAIFF(Handle sndHandle, std::ostream& output, const std::string& resourceName)
|
|
||||||
{
|
|
||||||
class AIFFChunkGuard
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
AIFFChunkGuard(Pomme::BigEndianOStream& theOutput, uint32_t chunkID)
|
|
||||||
: output(theOutput)
|
|
||||||
{
|
|
||||||
output.Write<uint32_t>(chunkID);
|
|
||||||
lengthFieldPosition = output.Tell();
|
|
||||||
output.Write<uint32_t>('#LEN'); // placeholder
|
|
||||||
}
|
|
||||||
|
|
||||||
~AIFFChunkGuard()
|
|
||||||
{
|
|
||||||
std::streampos endOfChunk = output.Tell();
|
|
||||||
std::streamoff chunkLength = endOfChunk - lengthFieldPosition - static_cast<std::streamoff>(4);
|
|
||||||
|
|
||||||
// Add zero pad byte if chunk length is odd
|
|
||||||
if (0 != (chunkLength & 1))
|
|
||||||
{
|
|
||||||
output.Write<uint8_t>(0);
|
|
||||||
endOfChunk += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
output.Goto(lengthFieldPosition);
|
|
||||||
output.Write<int32_t>(chunkLength);
|
|
||||||
output.Goto(endOfChunk);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Pomme::BigEndianOStream& output;
|
|
||||||
std::streampos lengthFieldPosition;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
SampledSoundInfo info;
|
|
||||||
GetSoundInfoFromSndResource(sndHandle, info);
|
|
||||||
|
|
||||||
char sampleRate80bit[10];
|
|
||||||
ConvertToIeeeExtended(info.sampleRate, sampleRate80bit);
|
|
||||||
|
|
||||||
Pomme::BigEndianOStream of(output);
|
|
||||||
|
|
||||||
bool hasLoop = info.loopEnd - info.loopStart > 1;
|
|
||||||
|
|
||||||
{
|
|
||||||
AIFFChunkGuard form(of, 'FORM');
|
|
||||||
of.Write<uint32_t>('AIFC');
|
|
||||||
|
|
||||||
{
|
|
||||||
AIFFChunkGuard chunk(of, 'FVER');
|
|
||||||
of.Write<uint32_t>(0xA2805140u);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
AIFFChunkGuard chunk(of, 'COMM');
|
|
||||||
of.Write<int16_t>(info.nChannels);
|
|
||||||
of.Write<uint32_t>(info.nPackets);
|
|
||||||
of.Write<int16_t>(info.codecBitDepth);
|
|
||||||
of.Write(sampleRate80bit, sizeof(sampleRate80bit));
|
|
||||||
of.Write<uint32_t>(info.compressionType);
|
|
||||||
|
|
||||||
std::string compressionName;
|
|
||||||
switch (info.compressionType)
|
|
||||||
{
|
|
||||||
case 'MAC3': compressionName = "MACE 3-to-1"; break;
|
|
||||||
case 'ima4': compressionName = "IMA 16 bit 4-to-1"; break;
|
|
||||||
case 'NONE': compressionName = "Signed PCM"; break;
|
|
||||||
case 'twos': compressionName = "Signed big-endian PCM"; break;
|
|
||||||
case 'sowt': compressionName = "Signed little-endian PCM"; break;
|
|
||||||
case 'raw ': compressionName = "Unsigned PCM"; break;
|
|
||||||
case 'ulaw': compressionName = "mu-law"; break;
|
|
||||||
case 'alaw': compressionName = "A-law"; break;
|
|
||||||
default: compressionName = "";
|
|
||||||
}
|
|
||||||
of.WritePascalString(compressionName, 2); // human-readable compression type pascal string
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasLoop)
|
|
||||||
{
|
|
||||||
AIFFChunkGuard chunk(of, 'MARK');
|
|
||||||
of.Write<int16_t>(2); // 2 markers
|
|
||||||
of.Write<int16_t>(101); // marker ID
|
|
||||||
of.Write<uint32_t>(info.loopStart);
|
|
||||||
of.WritePascalString("beg loop", 2);
|
|
||||||
of.Write<int16_t>(102); // marker ID
|
|
||||||
of.Write<uint32_t>(info.loopEnd);
|
|
||||||
of.WritePascalString("end loop", 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (info.baseNote != kMiddleC || hasLoop)
|
|
||||||
{
|
|
||||||
AIFFChunkGuard chunk(of, 'INST');
|
|
||||||
of.Write<int8_t>(info.baseNote);
|
|
||||||
of.Write<int8_t>(0); // detune
|
|
||||||
of.Write<int8_t>(0x00); // lowNote
|
|
||||||
of.Write<int8_t>(0x7F); // highNote
|
|
||||||
of.Write<int8_t>(0x00); // lowVelocity
|
|
||||||
of.Write<int8_t>(0x7F); // highVelocity
|
|
||||||
of.Write<int16_t>(0); // gain
|
|
||||||
of.Write<int16_t>(hasLoop? 1: 0); // sustainLoop.playMode
|
|
||||||
of.Write<int16_t>(hasLoop? 101: 0); // sustainLoop.beginLoop
|
|
||||||
of.Write<int16_t>(hasLoop? 102: 0); // sustainLoop.endLoop
|
|
||||||
of.Write<int16_t>(0);
|
|
||||||
of.Write<int16_t>(0);
|
|
||||||
of.Write<int16_t>(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!resourceName.empty())
|
|
||||||
{
|
|
||||||
AIFFChunkGuard chunk(of, 'NAME');
|
|
||||||
of.WriteRawString(resourceName);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
AIFFChunkGuard chunk(of, 'ANNO');
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << "Verbatim copy of data stream from 'snd ' resource.\n"
|
|
||||||
<< "MIDI base note: " << int(info.baseNote)
|
|
||||||
<< ", sustain loop: " << info.loopStart << "-" << info.loopEnd;
|
|
||||||
of.WriteRawString(ss.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
AIFFChunkGuard chunk(of, 'SSND');
|
|
||||||
of.Write<int32_t>(0); // offset; don't care
|
|
||||||
of.Write<int32_t>(0); // blockSize; don't care
|
|
||||||
of.Write(info.dataStart, info.compressedLength);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user