//----------------------------------------------------------------------------- bool XIFile::SetDataFromChip( const C700Driver *chip, int targetProgram, double tempo ) { mDataPos = 0; mDataUsed = 0; int start_prg; int end_prg; const InstParams *vp = chip->getVP(targetProgram); int selectBank = vp->bank; bool multisample = chip->GetMultiMode(selectBank); if ( multisample ) { start_prg = 0; end_prg = 127; } else { start_prg = end_prg = targetProgram; } XIFILEHEADER xfh; XIINSTRUMENTHEADER xih; XISAMPLEHEADER xsh; int nsamples = 0; // XI File Header memset(&xfh, 0, sizeof(xfh)); memcpy(xfh.extxi, "Extended Instrument: ", 21); if ( multisample ) { char multi_instname[][22] = { "Bank A (Multi)", "Bank B (Multi)", "Bank C (Multi)", "Bank D (Multi)" }; memcpy(xfh.name, multi_instname[selectBank], 22); } else { bool noname = false; if ( vp->pgname[0] == 0 ) { noname = true; } strncpy(xfh.name, vp->pgname, 22); if ( noname ) { memcpy(xfh.name, "Inst", 22); } } xfh.name[22] = 0x1A; memcpy(xfh.trkname, "FastTracker v2.00 ", 20); xfh.shsize = EndianU16_NtoL( 0x0102 ); if ( writeData( &xfh, sizeof(xfh),NULL ) == false ) { return false; } // XI Instrument Header memset(&xih, 0, sizeof(xih)); int vol = 64; if ( multisample ) { for ( int i=0; i<96; i++ ) { xih.snum[i] = chip->GetKeyMap(selectBank, i+12); } nsamples = RenumberKeyMap( xih.snum, 96 ); } else { for ( int i=0; i<96; i++ ) { xih.snum[i] = 0; } nsamples = 1; vol = (int)( abs(vp->volL) + abs(vp->volR) ) / 4; } //エンベロープの近似 if ( multisample ) { //サンプル毎には設定出来ないようなので非対応 for (int i=0; i<4; i++) { xih.venv[i*2] = EndianU16_NtoL( i*10 ); xih.venv[i*2+1] = EndianU16_NtoL( 64 ); } xih.venv[7] = 0; } else { xih.venv[0] = 0; if ( vp->ar == 15 ) { xih.venv[1] = EndianU16_NtoL( vol ); } else { xih.venv[1] = 0; } xih.venv[2] = EndianU16_NtoL( GetARTicks( vp->ar, tempo ) ); //tick数値はテンポ値に依存する xih.venv[3] = EndianU16_NtoL( vol ); xih.venv[4] = EndianU16_NtoL( xih.venv[2] + GetDRTicks( vp->dr, tempo ) ); xih.venv[5] = EndianU16_NtoL( vol * (vp->sl + 1) / 8 ); if ((vp->sr == 0) || vp->sustainMode) { xih.venv[6] = EndianU16_NtoL( xih.venv[4]+1 ); xih.venv[7] = EndianU16_NtoL( xih.venv[5] ); } else { xih.venv[6] = EndianU16_NtoL( xih.venv[4] + GetSRTicks( vp->sr, tempo ) ); xih.venv[7] = EndianU16_NtoL( vol / 10 ); } } xih.vnum = 4; xih.pnum = 0; xih.vsustain = 3; xih.vloops = 3; xih.vloope = 3; xih.psustain = 0; xih.ploops = 0; xih.ploope = 0; xih.vtype = 3; //ENV_VOLUME + ENV_VOLSUSTAIN xih.ptype = 0; xih.volfade = EndianU16_NtoL( 32767 ); xih.reserved2 = EndianU16_NtoL( nsamples ); if ( writeData( &xih, sizeof(xih),NULL ) == false ) { return false; } // XI Sample Headers for (int ismp=start_prg; ismp<=end_prg; ismp++) { if ( chip->getVP(ismp)->hasBrrData() && chip->getVP(ismp)->bank == selectBank ) { //元ファイルのヘッダー情報を読み込む bool existSrcFile = false; if ( chip->getVP(ismp)->sourceFile[0] ) { AudioFile::InstData inst; int numSamples; AudioFile origFile(chip->getVP(ismp)->sourceFile,false); origFile.Load(); if ( origFile.IsLoaded() ) { numSamples = origFile.GetLoadedSamples(); origFile.GetInstData(&inst); xsh.samplen = EndianU32_NtoL( numSamples * 2 ); xsh.loopstart = EndianU32_NtoL( inst.lp * 2 ); xsh.looplen = EndianU32_NtoL( (inst.lp_end - inst.lp) * 2 ); existSrcFile = true; } } if ( existSrcFile == false ) { xsh.samplen = EndianU32_NtoL( chip->getVP(ismp)->brrSize()/9*32 ); xsh.loopstart = EndianU32_NtoL( chip->getVP(ismp)->lp/9*32 ); xsh.looplen = EndianU32_NtoL( xsh.samplen - xsh.loopstart ); } double avr = ( abs(chip->getVP(ismp)->volL) + abs(chip->getVP(ismp)->volR) ) / 2; double pan = (abs(chip->getVP(ismp)->volR) * 128) / avr; if ( pan > 255 ) pan = 255; xsh.vol = 64; //変化しない? xsh.pan = pan; xsh.type = 0x10; //CHN_16BIT if ( chip->getVP(ismp)->loop ) { xsh.type |= 0x01; //Normal Loop } double trans = 12*(log(chip->getVP(ismp)->rate / 8363.0)/log(2.0)); int trans_i = (trans + (60-chip->getVP(ismp)->basekey) ) * 128 + 0.5; xsh.relnote = trans_i >> 7; xsh.finetune = trans_i & 0x7f; xsh.res = 0; if ( chip->getVP(ismp)->pgname[0] == 0 ) { strncpy(xsh.name, "Sample", 21); } else { strncpy(xsh.name, chip->getVP(ismp)->pgname, 21); } if ( writeData( &xsh, sizeof(xsh),NULL ) == false ) { return false; } } }
int main(int argc, char **argv) try { if (argc != 3) { printUsageAndDie(argv[0]); } std::ifstream origFile(argv[1]); if (! origFile) { throw std::runtime_error("Cannot open " + std::string(argv[1])); } std::ifstream splitFile(argv[2]); if (! splitFile) { throw std::runtime_error("Cannot open " + std::string(argv[2])); } unsigned startPos = 0; int origPos = 0; std::string line; unsigned lineNo = 0; while (std::getline(splitFile, line)) { ++lineNo; unsigned endPos = startPos + line.size(); unsigned origStartPos; if (line.size() == 0) { /// empty line origStartPos = origPos; } else { /// collect heading spaces std::string headingWs; for (std::string::const_iterator ch = line.begin(); ch != line.end(); ++ch) { if (std::isspace(*ch)) { headingWs += *ch; } else { break; } } // if (line[0] == ' ') { // throw std::runtime_error( // "Error: Split text contains a heading space"); // } /// skip newlines in the original file char origChar; while (origFile.get(origChar)) { ++origPos; if (origChar != '\n') { origFile.unget(); --origPos; break; } } /// collect spaces in the original file std::string origWs; while (origFile.get(origChar)) { ++origPos; if (origChar == ' ' || origChar == '\t') { origWs += origChar; } else { origFile.unget(); --origPos; break; } } #if 0 /// skip spaces and newlines in the original file char origChar; do { if (! origFile.get(origChar)) { throw std::runtime_error( "Split/original text do not match"); } ++origPos; } while (origChar == ' ' || origChar == '\n'); origFile.unget(); --origPos; #endif /// check if the heading space part has a corresponding region /// in the original file if (origWs.size() < headingWs.size()) { throw std::runtime_error("Split/original text do not match"); } unsigned skipLen = origWs.size() - headingWs.size(); if (! headingWs.empty() && headingWs != origWs.substr(skipLen)) { throw std::runtime_error("Split/original text do not match"); } origStartPos = origPos - headingWs.size(); /// Check the identity for the rest of the line for (unsigned i = headingWs.size(); i < line.size(); ++i) { if (! origFile.get(origChar) || origChar != line[i]) { std::string msg = errorMsgLong( origPos, origChar, lineNo, i, line[i]); throw std::runtime_error(msg); } ++origPos; } } std::cout << startPos << '\t' << endPos << '\t' << origStartPos << std::endl; /// +1 to skip the new line character startPos = endPos + 1; } return 0; } catch (std::runtime_error &e) { std::cerr << e.what() << std::endl; exit(1); } catch (...) { std::cerr << "Unknown exception" << std::endl; exit(1); }