void QuickTimeDecoder::queueNextAudioChunk() { AudioSampleDesc *entry = (AudioSampleDesc *)_tracks[_audioTrackIndex]->sampleDescs[0]; Common::MemoryWriteStreamDynamic *wStream = new Common::MemoryWriteStreamDynamic(); _fd->seek(_tracks[_audioTrackIndex]->chunkOffsets[_curAudioChunk]); // First, we have to get the sample count uint32 sampleCount = entry->getAudioChunkSampleCount(_curAudioChunk); assert(sampleCount); if (isOldDemuxing()) { // Old-style audio demuxing // Then calculate the right sizes while (sampleCount > 0) { uint32 samples = 0, size = 0; if (entry->_samplesPerFrame >= 160) { samples = entry->_samplesPerFrame; size = entry->_bytesPerFrame; } else if (entry->_samplesPerFrame > 1) { samples = MIN<uint32>((1024 / entry->_samplesPerFrame) * entry->_samplesPerFrame, sampleCount); size = (samples / entry->_samplesPerFrame) * entry->_bytesPerFrame; } else { samples = MIN<uint32>(1024, sampleCount); size = samples * _tracks[_audioTrackIndex]->sampleSize; } // Now, we read in the data for this data and output it byte *data = (byte *)malloc(size); _fd->read(data, size); wStream->write(data, size); free(data); sampleCount -= samples; } } else { // New-style audio demuxing // Find our starting sample uint32 startSample = 0; for (uint32 i = 0; i < _curAudioChunk; i++) startSample += entry->getAudioChunkSampleCount(i); for (uint32 i = 0; i < sampleCount; i++) { uint32 size = (_tracks[_audioTrackIndex]->sampleSize != 0) ? _tracks[_audioTrackIndex]->sampleSize : _tracks[_audioTrackIndex]->sampleSizes[i + startSample]; // Now, we read in the data for this data and output it byte *data = (byte *)malloc(size); _fd->read(data, size); wStream->write(data, size); free(data); } } // Now queue the buffer queueSound(entry->createAudioStream(new Common::MemoryReadStream(wStream->getData(), wStream->size(), true))); delete wStream; _curAudioChunk++; }
Common::SeekableReadStream *PEFile::getResource(uint32 index, bool UNUSED(tryNoCopy)) const { // Convert from the PE cursor group/cursor format to the standalone // cursor format. Common::MemoryWriteStreamDynamic out; Common::SeekableReadStream *cursorGroup = _peFile->getResource(Common::kPEGroupCursor, index); if (!cursorGroup) throw Common::Exception("No such PE resource %u", index); // Cursor Group Header out.writeUint16LE(cursorGroup->readUint16LE()); out.writeUint16LE(cursorGroup->readUint16LE()); uint16 cursorCount = cursorGroup->readUint16LE(); out.writeUint16LE(cursorCount); std::vector<Common::SeekableReadStream *> cursorStreams; cursorStreams.resize(cursorCount); uint32 startOffset = 6 + cursorCount * 16; for (uint16 i = 0; i < cursorCount; i++) { out.writeByte(cursorGroup->readUint16LE()); // width out.writeByte(cursorGroup->readUint16LE() / 2); // height cursorGroup->readUint16LE(); // planes out.writeByte(cursorGroup->readUint16LE()); // bits per pixel out.writeByte(0); // reserved cursorGroup->readUint32LE(); // data size uint16 id = cursorGroup->readUint16LE(); Common::SeekableReadStream *cursor = _peFile->getResource(Common::kPECursor, id); if (!cursor) { delete cursorGroup; throw Common::Exception("Could not get cursor resource %d", id); } out.writeUint16LE(cursor->readUint16LE()); // hotspot X out.writeUint16LE(cursor->readUint16LE()); // hotspot Y out.writeUint32LE(cursor->size() - 4); // size out.writeUint32LE(startOffset); // offset startOffset += cursor->size() - 4; cursorStreams[i] = cursor; } for (uint32 i = 0; i < cursorStreams.size(); i++) { byte *data = new byte[cursorStreams[i]->size() - 4]; cursorStreams[i]->read(data, cursorStreams[i]->size() - 4); out.write(data, cursorStreams[i]->size() - 4); delete[] data; delete cursorStreams[i]; } delete cursorGroup; return new Common::MemoryReadStream(out.getData(), out.size(), true); }
static uint32 convertSND2MIDI(byte *snddata, byte **data) { int32 lp, ep; int n; double ll; Common::MemoryWriteStreamDynamic st; ll = log10(pow(2.0, 1.0 / 12.0)); /* Header */ st.write("MThd", 4); st.writeUint32BE(6); st.writeUint16BE(1); /* mode */ st.writeUint16BE(3); /* number of tracks */ st.writeUint16BE(192); /* ticks / quarter */ fprintf(_fd, "window.sound%d = [\n", _index); for (n = 0; n < 3; n++) { uint16 start, end, pos; st.write("MTrk", 4); lp = st.pos(); st.writeUint32BE(0); /* chunklength */ writeDelta(&st, 0); /* set instrument */ st.writeByte(0xc0 + n); st.writeByte(instr[n]); start = snddata[n * 2 + 0] | (snddata[n * 2 + 1] << 8); end = ((snddata[n * 2 + 2] | (snddata[n * 2 + 3] << 8))) - 5; fprintf(_fd, " ["); bool first = true; for (pos = start; pos < end; pos += 5) { uint16 freq, dur; dur = (snddata[pos + 0] | (snddata[pos + 1] << 8)) * SPEED_FACTOR; freq = ((snddata[pos + 2] & 0x3F) << 4) + (snddata[pos + 3] & 0x0F); if (snddata[pos + 2] > 0) { double fr; int note; /* I don't know, what frequency equals midi note 0 ... */ /* This moves the song 4 octaves down: */ fr = (log10(111860.0 / (double)freq) / ll) - 48; note = (int)floor(fr + 0.5); if (note < 0) note = 0; if (note > 127) note = 127; /* note on */ writeDelta(&st, 0); st.writeByte(144 + n); st.writeByte(note); st.writeByte(100); /* note off */ writeDelta(&st, dur); st.writeByte(128 + n); st.writeByte(note); st.writeByte(0); if ( first ) first = false; else fprintf(_fd, ","); fprintf(_fd, "%d,%d", note, dur/SPEED_FACTOR); } else { /* note on */ writeDelta(&st, 0); st.writeByte(144 + n); st.writeByte(0); st.writeByte(0); /* note off */ writeDelta(&st, dur); st.writeByte(128 + n); st.writeByte(0); st.writeByte(0); if ( first ) first = false; else fprintf(_fd, ","); fprintf(_fd, "%d,%d", -1, dur/SPEED_FACTOR); } } fprintf(_fd, n<2 ? "],\n" : "]\n"); writeDelta(&st, 0); st.writeByte(0xff); st.writeByte(0x2f); st.writeByte(0x0); ep = st.pos(); st.seek(lp, SEEK_SET); st.writeUint32BE((ep - lp) - 4); st.seek(ep, SEEK_SET); } fprintf(_fd, "];\n"); // *data = st.getData(); return st.pos(); }
Common::MemoryReadStream *LanguageManager::preParseColorCodes(Common::SeekableReadStream &stream) { Common::MemoryWriteStreamDynamic output; output.reserve(stream.size()); int state = 0; std::vector<byte> collect; collect.reserve(6); byte color[3]; byte b; while (stream.read(&b, 1) == 1) { if (state == 0) { if (b == '<') { collect.push_back(b); state = 1; } else output.writeByte(b); continue; } if (state == 1) { if (b == 'c') { collect.push_back(b); state = 2; } else { output.write(&collect[0], collect.size()); output.writeByte(b); collect.clear(); state = 0; } continue; } if ((state == 2) || (state == 3) || (state == 4)) { collect.push_back(b); color[state - 2] = b; state++; continue; } if (state == 5) { if (b == '>') { Common::UString c = Common::UString::format("<c%02X%02X%02X%02X>", (uint8) color[0], (uint8) color[1], (uint8) color[2], (uint8) 0xFF); output.writeString(c); collect.clear(); state = 0; } else { output.write(&collect[0], collect.size()); output.writeByte(b); collect.clear(); state = 0; } continue; } } return new Common::MemoryReadStream(output.getData(), output.size(), true); }