示例#1
0
//-----------------------------------------------------------------------------
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;
			}
		}
	}
示例#2
0
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);
}