but personally I think it could use a bit more of a in-your-face melody. It currently sounds a bit... unfinished for some reason
Music
#181
Posted 15 January 2009 - 10:56 AM
but personally I think it could use a bit more of a in-your-face melody. It currently sounds a bit... unfinished for some reason
#182
Posted 15 January 2009 - 11:32 AM
#183
Posted 16 January 2009 - 07:38 AM
I've studied the Sonics' orchestrations (on Sonic 1 & 2) and I think I got the right style down. Listen to "the Flying Circus" and please tel me what you think about it (I know I still have to change this boring end).
http://www.everyoneweb.fr/SailuMusic/
It's just the composition, made with Guitar Pro. I would do this music again with a better software if I was sure almost all of you enjoyed it.
I could redo it with a software I usually use (listen "Hightech City" for an example) or with a software which emulates Genesis sounds. Do you want a cleaner and modern sound, or a old sonic-like rendering ?
#184
Posted 16 January 2009 - 04:54 PM
Sailu Baru, on Jan 16 2009, 06:38 AM, said:
Definitely the former, although you could do certain parts with the Genesis rendering. Like someone a while back in this topic said, it would be great to have the modern sounds alongside the Genesis ones.
#185
Posted 16 January 2009 - 06:38 PM
It's mostly bass voices from Sonic 1-S3K. README details where to put them.
Fun stuff I found when making these:
The lead voice from Labyrinth is the exact same as the bass voice from Mystic Cave.
The bass from Marble and Starlight are almost exactly the same (the level of Carrier 2 is altered).
The bass from Scrap Brain and Emerald Hill are almost exactly the same (the level of Carrier 2 is altered).
#186
Posted 16 January 2009 - 07:47 PM
#187
Posted 16 January 2009 - 08:45 PM
That being said, I can do .OPMs, if those will work equally well (via VOPM's import/export feature).
EDIT: Nevermind, OPM's are failing miserably, hang on a bit.
#188
Posted 16 January 2009 - 11:29 PM
How is OPM failing?
PS - I have alternate OPM files ripped from VGZ files of the Sonic music, if you want to test then.
#189
Posted 16 January 2009 - 11:52 PM
I'm going to attempt to write a little program to convert .y12 dumps from Gens KMod to .OPM voice segments.
#190
Posted 16 January 2009 - 11:59 PM
McGuirk, on Jan 16 2009, 11:52 PM, said:
I'm going to attempt to write a little program to convert .y12 dumps from Gens KMod to .OPM voice segments.
Nine channels is all you need; the Genesis sound processor only supports six. Use this awk script to split OPM files into individual settings and drop the no name ones:
# splitopm: split opm file into one per instrument
# pietro gagliardi - 6 january 2009
# usage: splitopm file.opm output-directory
BEGIN {
# Change this if your OS needs it
DIR_SEPARATOR = "/"
if (ARGC != 3) {
print "usage: " ARGV[0] " file.opm output-directory"
exit 1
}
outdir = ARGV[2]
ARGV[2] = ""
ARGC--
RS = ""
FS = OFS = "\n"
}
/^\/\// { next }
!/^@/ { print ARGV[1] ": bad input file"; exit 1 }
{
instrname = substr($1, index($1, " ") + 1)
if (tolower(instrname) == "no name")
next
oldinstrname = instrname
gsub(/[^A-Za-z0-9_]/, "", instrname)
filename = outdir DIR_SEPARATOR instrname ".opm"
$1 = "@:0 " oldinstrname # convert to bank 0
print > filename
close(filename)
inst++
}
You may need to change the line
$1 = "@:0 " oldinstrname # convert to bank 0
to
$1 = "@:1 " oldinstrname # convert to bank 1
if the script doesn't result in files that can be imported, but I don't know.
#191
Posted 17 January 2009 - 12:28 AM
Andlabs, on Jan 16 2009, 10:59 PM, said:
McGuirk, on Jan 16 2009, 11:52 PM, said:
I'm going to attempt to write a little program to convert .y12 dumps from Gens KMod to .OPM voice segments.
Nine channels is all you need; the Genesis sound processor only supports six....
Sorry, I said that wrong, it outputs nine voices, and 118 "no Name" voices to a .OPM file.
Thanks for the script though. I'm still gonna attempt to write this converter though: Out of practice freshman level C++ powers, activate!
#192
Posted 17 January 2009 - 01:52 PM
#193
Posted 17 January 2009 - 07:18 PM
It trashes some thing numbers that aren't visible in VOPM, and I don't know what they are, but ditching them isn't hurting anything (yet).
If anyone encounters any problems, let me know and all that. Also, if anyone knows what they're doing with Windows programming and wants to write a GUI or at least get some sort of drag and drop going, I'd be more than happy to provide the filthy, filthy source for this clunker.
Converter.exe
Anyway, this program will convert a .y12 dump provided by Gens KMod to a .OPM file that you can import into VOPM.
Sadly, I cannot get drag and drop to work, so you folks are stuck running it from a command line for now, like so:
"converter.exe chan5.y12"
Sexy.
For now it works ok, I've done about 15 test runs and haven't had an issue yet, I just worry about those dropped numbers.
#194
Posted 17 January 2009 - 08:10 PM
McGuirk, on Jan 17 2009, 07:18 PM, said:
Or, I could help you clean it up :-P
#195
Posted 17 January 2009 - 08:35 PM
A lot of the monotonous stuff can be function'd, particularly the printing parts. But I'm wore out:P
In a codebox because of encoding issues between windows and linux.
If you're brave the source file itself can be found here.
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
/*
* converter.cpp
* Copyright © Jake Reed 2009
*
* converter.cpp is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* converter.cpp is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see .
*/
#include
#include
#include
#include
using namespace std;
char fixTL(char c)
{
// *HACK*
// The first bit is 1 in the dump.
// I don't know what it's for, and
// it works fine if I just drop it.
// Clarify: The first bit SHOULD
// NOT be 1.
// TL is 0-127, 127=7 bits
unsigned char temp = c;
temp = (temp << 1);
temp = (temp >> 1);
return temp;
}
string expandDetMul(char c)
{
// First 4 bits = Det
// Last 4 bits = Mul
string out;
char det = (char)0;
char mul = (char)0;
unsigned char temp = c;
for (int I=7; I>=4; I--)
{
char bit = ((temp >> I) & 1);
det = (det << 1 | bit);
}
for (int I=3; I>=0; I--)
{
char bit = ((temp >> I) & 1);
mul = (mul << 1 | bit);
}
out = det;
out += mul;
return out;
}
string expandKsAtk(char c)
{
// First 2 bits = KS
// Followed by a 0 bit
// Last 5 bits = Atk
string out;
char KS = (char)0;
char atk = (char)0;
unsigned char temp = c;
for (int I=7; I>=6; I--)
{
char bit = ((temp >> I) & 1);
KS = (KS << 1 | bit);
}
for (int I=4; I>=0; I--)
{
char bit = ((temp >> I) & 1);
atk = (atk << 1 | bit);
}
out = KS;
out += atk;
return out;
}
string expandSlRel(char c)
{
// First 4 bits = Sus Level
// Last 4 bits = Rel
string out;
char sus = (char)0;
char rel = (char)0;
unsigned char temp = c;
for (int I=7; I>=4; I--)
{
char bit = ((temp >> I) & 1);
sus = (sus << 1 | bit);
}
for (int I=3; I>=0; I--)
{
char bit = ((temp >> I) & 1);
rel = (rel << 1 | bit);
}
out = sus;
out += rel;
return out;
}
struct OP
{
/*
*Detune
*Multiple
*Total Level
*Key Scale
*Attack
*Decay
*Sustain (Second Decay)
*Sus Level
*Release
*/
// Single operator attributes
unsigned char det;
unsigned char mul;
unsigned char tLevel;
unsigned char kScale;
unsigned char atk;
unsigned char dec;
unsigned char sus;
unsigned char sLevel;
unsigned char rel;
// Compressed operator attributes
unsigned char det_mul;
unsigned char kS_atk;
unsigned char sL_rel;
};
struct Channel
{
char connection;
char feedback;
};
int main(int argc, char* argv[])
{
if (argc <= 1)
{
cout << "Usage: " << argv[0] << " " << endl;
exit(1);
}
char *pFilename = argv[1];
//char inFileName[] = "test.y12";
//char outFileName[] = "test.opm";
Channel channel;
OP M1;
OP M2;
OP C1;
OP C2;
ifstream inFile(pFilename, ios::in | ios::binary);
char* readBuffer = new char [0];
/****************************************
*** READS ***
****************************************/
// Read M1
inFile.read(readBuffer, 1);
M1.det_mul = readBuffer[0];
inFile.read(readBuffer, 1);
M1.tLevel = readBuffer[0];
inFile.read(readBuffer, 1);
M1.kS_atk = readBuffer[0];
inFile.read(readBuffer, 1);
M1.dec = readBuffer[0];
inFile.read(readBuffer, 1);
M1.sus = readBuffer[0];
inFile.read(readBuffer, 1);
M1.sL_rel = readBuffer[0];
for (int I = 1; I <= 10; I++)
{
inFile.read(readBuffer, 1);
}
// Read M2
inFile.read(readBuffer, 1);
M2.det_mul = readBuffer[0];
inFile.read(readBuffer, 1);
M2.tLevel = readBuffer[0];
inFile.read(readBuffer, 1);
M2.kS_atk = readBuffer[0];
inFile.read(readBuffer, 1);
M2.dec = readBuffer[0];
inFile.read(readBuffer, 1);
M2.sus = readBuffer[0];
inFile.read(readBuffer, 1);
M2.sL_rel = readBuffer[0];
for (int I = 1; I <= 10; I++)
{
inFile.read(readBuffer, 1);
}
// Read C1
inFile.read(readBuffer, 1);
C1.det_mul = readBuffer[0];
inFile.read(readBuffer, 1);
C1.tLevel = readBuffer[0];
inFile.read(readBuffer, 1);
C1.kS_atk = readBuffer[0];
inFile.read(readBuffer, 1);
C1.dec = readBuffer[0];
inFile.read(readBuffer, 1);
C1.sus = readBuffer[0];
inFile.read(readBuffer, 1);
C1.sL_rel = readBuffer[0];
for (int I = 1; I <= 10; I++)
{
inFile.read(readBuffer, 1);
}
// Read C2
inFile.read(readBuffer, 1);
C2.det_mul = readBuffer[0];
inFile.read(readBuffer, 1);
C2.tLevel = readBuffer[0];
inFile.read(readBuffer, 1);
C2.kS_atk = readBuffer[0];
inFile.read(readBuffer, 1);
C2.dec = readBuffer[0];
inFile.read(readBuffer, 1);
C2.sus = readBuffer[0];
inFile.read(readBuffer, 1);
C2.sL_rel = readBuffer[0];
for (int I = 1; I <= 10; I++)
{
inFile.read(readBuffer, 1);
}
// Channel
inFile.read(readBuffer, 1);
channel.feedback = readBuffer[0];
inFile.read(readBuffer, 1);
channel.connection = readBuffer[0];
inFile.close();
/****************************************
*** EXPAND ***
****************************************/
// M1
string out = expandDetMul(M1.det_mul);
M1.det = out.at(0);
M1.mul = out.at(1);
out = expandKsAtk(M1.kS_atk);
M1.kScale = out.at(0);
M1.atk = out.at(1);
out = expandSlRel(M1.sL_rel);
M1.sLevel = out.at(0);
M1.rel = out.at(1);
char temp = fixTL(M1.tLevel);
M1.tLevel = temp;
// M2
out = expandDetMul(M2.det_mul);
M2.det = out.at(0);
M2.mul = out.at(1);
out = expandKsAtk(M2.kS_atk);
M2.kScale = out.at(0);
M2.atk = out.at(1);
out = expandSlRel(M2.sL_rel);
M2.sLevel = out.at(0);
M2.rel = out.at(1);
temp = fixTL(M2.tLevel);
M2.tLevel = temp;
// C1
out = expandDetMul(C1.det_mul);
C1.det = out.at(0);
C1.mul = out.at(1);
out = expandKsAtk(C1.kS_atk);
C1.kScale = out.at(0);
C1.atk = out.at(1);
out = expandSlRel(C1.sL_rel);
C1.sLevel = out.at(0);
C1.rel = out.at(1);
temp = fixTL(C1.tLevel);
C1.tLevel = temp;
// C2
out = expandDetMul(C2.det_mul);
C2.det = out.at(0);
C2.mul = out.at(1);
out = expandKsAtk(C2.kS_atk);
C2.kScale = out.at(0);
C2.atk = out.at(1);
out = expandSlRel(C2.sL_rel);
C2.sLevel = out.at(0);
C2.rel = out.at(1);
temp = fixTL(C2.tLevel);
C2.tLevel = temp;
/****************************************
*** PRINT ***
****************************************/
fstream outFile("out.OPM", ios::out);
// Heading
outFile << "@:0 " << pFilename << "\n";
outFile << "LFO: 0 0 0 0 0\n";
outFile << "CH:"
<< setw(4) << "64"
<< setw(4) << (int)channel.connection
<< setw(4) << (int)channel.feedback
<< setw(4) << "0"
<< setw(4) << "0"
<< setw(4) << "120"
<< setw(4) << "0"
<< "\n";
outFile << "M1:"
<< setw(4) << (int)M1.atk
<< setw(4) << (int)M1.dec
<< setw(4) << (int)M1.sus
<< setw(4) << (int)M1.rel
<< setw(4) << (int)M1.sLevel
<< setw(4) << (int)M1.tLevel
<< setw(4) << (int)M1.kScale
<< setw(4) << (int)M1.mul
<< setw(4) << (int)M1.det
<< setw(4) << 0
<< setw(4) << 0 << "\n";
outFile << "C1:"
<< setw(4) << (int)C1.atk
<< setw(4) << (int)C1.dec
<< setw(4) << (int)C1.sus
<< setw(4) << (int)C1.rel
<< setw(4) << (int)C1.sLevel
<< setw(4) << (int)C1.tLevel
<< setw(4) << (int)C1.kScale
<< setw(4) << (int)C1.mul
<< setw(4) << (int)C1.det
<< setw(4) << 0
<< setw(4) << 0 << "\n";
outFile << "M2:"
<< setw(4) << (int)M2.atk
<< setw(4) << (int)M2.dec
<< setw(4) << (int)M2.sus
<< setw(4) << (int)M2.rel
<< setw(4) << (int)M2.sLevel
<< setw(4) << (int)M2.tLevel
<< setw(4) << (int)M2.kScale
<< setw(4) << (int)M2.mul
<< setw(4) << (int)M2.det
<< setw(4) << 0
<< setw(4) << 0 << "\n";
outFile << "C2:"
<< setw(4) << (int)C2.atk
<< setw(4) << (int)C2.dec
<< setw(4) << (int)C2.sus
<< setw(4) << (int)C2.rel
<< setw(4) << (int)C2.sLevel
<< setw(4) << (int)C2.tLevel
<< setw(4) << (int)C2.kScale
<< setw(4) << (int)C2.mul
<< setw(4) << (int)C2.det
<< setw(4) << 0
<< setw(4) << 0 << "\n";
outFile.close();
return 0;
}
That's right, it's GPL'd =P
I started going in anjuta before I got annoyed and whipped out text editor and g++.
