Sonic and Sega Retro Message Board: Music - Sonic and Sega Retro Message Board

Jump to content

Hey there, Guest!  (Log In · Register) Help
  • 16 Pages +
  • ◄ First
  • 12
  • 13
  • 14
  • 15
  • 16
    Locked
    Locked Forum

Music

#196 User is offline Andlabs 

Posted 18 January 2009 - 12:45 AM

  • 「いっきまーす」
  • Posts: 2175
  • Joined: 11-July 08
  • Gender:Male
  • Project:Writing my own MD/Genesis sound driver :D
  • Wiki edits:7,061
Other than the monotony, this code looks good. Just explain what you are doing in the helper functions and you have a pearl.

Windows is up. VOPM is up. Cubasis InWired is up. My OPM tracks are all ripped from VGZ files. I have Sonic 3 audio samples ready. Soon!
This post has been edited by Andlabs: 18 January 2009 - 12:49 AM

#197 User is offline McGuirk 

Posted 18 January 2009 - 04:41 AM

  • The Egg-Man Cometh.
  • Posts: 576
  • Joined: 09-October 03
  • Gender:Male
  • Location:Fort Worth, Texas, USA
  • Project:Making a Full-Sized Egg Carrier in Minecraft.
  • Wiki edits:3
Fist off, the dumps are compressed.

I'll explain.

Here's the values for OP1 channel 3 of the exercise music from Dr. Robotnik's Mean Bean Machine:

Detune:       0x03
Multiple:     0x09
Total Level:  0x17
Rate Scaling: 0x00
Attack Rate:  0x1F
First Decay:  0x0C
Second Decay: 0x07
Sub Level:    0x06
Release Rate: 0x06



03 09 12 00 1F 0C 07 06 06

Now, here's the dump from the .y12 file:

39 17 1F 0C 07 26

Here's what each of them is:

(Unless specified otherwise,
the helper functions take the compressed
byte as a character for a parameter, then
returns a std::string of the decompressed
bytes as 2 characters)

----

39:
Detune and Multiple grouped.
1 nybble per value. expandDetMul()
splits the bits between the two.

----

17:
Total Level, whole byte.

NOTE: The value does not include the
whole byte. TL's value is 0-127,
so the first bit is ignored.

I don't know why it's sometimes 1 in the dumps.
fixTL() takes TL as a char, sets the first
bit to zero via bit shifts, and returns the
altered char.

----

1F:
Rate Scaling and Attack Rate.
This one is more complex. Of
the byte, the first two bits
are the Rate Scaling, followed
by a 0 bit, followed by the
Attack rate in the last 5 bits.

IE: RS0AtkRt
1F:00011111

expandKsAtk() splits the bits

----

0C:
First Decay, whole byte.

----

07:
Second Decay, whole byte.

----

26:
Sustain Level and Release rate:
After more research these two
values are always equal. They
are represented by the second
nybble, I was splitting in two
before. This means I'll be
posting a revised source file
at the bottom of this post.
The 2 can be dropped.

----

These are followed by 10 bytes
of 0x00's. Trash for now.
Repeat for 3 more OP's + 10
byte buffer between. Next,

One byte for the channel's
connection type:
0x00 - 0x07

Very next byte is Channel's
feedback level:
0x00 - 0x07

Rest is crap.

That's the overview.

The variables should cover
themselves in the comments
near them.

Feel free to ask more detailed
questions if I left something out.

Here's the updates source:

/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
/*
 * converter.cpp
 * Copyright © Jake Reed 2009 <[email protected]>
 * 
 * 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 <http://www.gnu.org/licenses/>.
 */

#include <iostream>
#include <string>
#include <iomanip>
#include <fstream>

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 = Crap
        // Last 4 bits = Both Values
    
    string out;
    
    char rel = (char)0;

    unsigned char temp = c;
    
    for (int I=3; I>=0; I--) 
        {
            char bit = ((temp >> I) & 1);
            rel = (rel << 1 | bit); 
        }

    out = rel;
    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] << " <Filename>" << 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.connection = readBuffer[0];
    
    inFile.read(readBuffer, 1);
    channel.feedback = 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.feedback
         << setw(4) << (int)channel.connection
         << 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;
}




#198 User is offline XCubed 

Posted 18 January 2009 - 09:23 AM

  • Will Someday Own a Rent-A-Center
  • Posts: 2909
  • Joined: 23-November 04
  • Gender:Male
  • Location:Ft. Lauderdale, FL
  • Wiki edits:5

View PostMcGuirk, on Jan 16 2009, 06:38 PM, said:

Here are some FL Studio channel presets for VOPM.

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).



You motherfucker, I need to make sweet love to you NOW!!! Your directions were a little different from my version of FL Studio, but with some tooling around with the files I was able to get it to work! I LOVE YOU! I want you to have my babies. I can make sweet lovin closer to Genesis sounds that I ever could have before! Sorry for the profanity, but this has made me so damn happy! I don't know how the fuck you did this, but either way you have my love now and forever McGuirk!
This post has been edited by XCubed: 18 January 2009 - 09:26 AM

#199 User is offline Andlabs 

Posted 19 January 2009 - 09:50 AM

  • 「いっきまーす」
  • Posts: 2175
  • Joined: 11-July 08
  • Gender:Male
  • Project:Writing my own MD/Genesis sound driver :D
  • Wiki edits:7,061
Is there a way to emulate the Programmable Sound Generator? I noticed that some songs, such as Lava Reef Act 1, use it alongside the OPM FM channels.

#200 User is offline muteKi 

Posted 19 January 2009 - 11:57 AM

  • Fuck it
  • Posts: 7427
  • Joined: 03-March 05
  • Gender:Male
  • Wiki edits:91
There must be a decent square wave VST out there somewhere...

#201 User is offline roxahris 

Posted 20 January 2009 - 01:47 AM

  • Everyone's a hypocrite. Take my word for it.
  • Posts: 1221
  • Joined: 24-January 07
  • Gender:Male
  • Project:Doing anything at all
  • Wiki edits:30
I thought I'd contribute to those making Mega Drive-style music.
Here is a zip file containing all the FM voices from Sonic 1 (and a few square wave voices too, I think) in opm format. To load opm files into VOPM, use the import function. If you want to use these voices in something that uses tfi files, look for vopmxtfi. Thanks.

#202 User is offline Chimpo 

Posted 22 January 2009 - 08:22 PM

  • Posts: 7172
  • Joined: 26-July 06
  • Gender:Not Telling
Moved the entire thread over mainly for the discussions going on. And for reference of any previous material or suggestions submitted. If you have the time, would you kindly read what you can.

Right now though, let's get on track. What I want to hear is some concepts of what you think the next Sonic game should sound like.

Like so!

(I think that's by Twaker.)

#203 User is offline Stealth 

Posted 22 January 2009 - 10:52 PM

  • Posts: 546
  • Joined: 31-July 05
  • Gender:Male
  • Project:HCGE, Project HC, Sonic Megamix, SonED2, [...]
  • Wiki edits:19

View PostmuteKi, on Jan 22 2009, 03:16 PM, said:


That first one is ok, but it makes me think "end credits" more than it does "first tropical zone"

View PostmuteKi, on Jan 22 2009, 04:20 PM, said:

[Course, in a perfect world it would sound more like this: http://www.box.net/shared/uki4p3xu9u]

View PostChimpo, on Jan 22 2009, 05:22 PM, said:

Right now though, let's get on track. What I want to hear is some concepts of what you think the next Sonic game should sound like.

Like so!

I sincerely hope we aren't using these kinds of instrumentation. The first one just sounds poor quality and in the wrong style. The second one, The melody might be ok, but I can't get past the sound. I don't know what that is in the front, but it sounds like the universe itself took a cosmic dump

#204 User is offline Phoebius 

Posted 23 January 2009 - 05:40 AM

  • Coucou
  • Posts: 1567
  • Joined: 16-August 03
  • Gender:Male
  • Location:France
  • Project:iOS Game
Can we at least decide if we're using MD style music or not?

Because...

http://steevboss.free.fr/The%20Zone,%20The...Glam%20City.mp3

http://steevboss.fre...watertemple.mp3

http://steevboss.free.fr/endgame.mp3

http://steevboss.free.fr/skysurf2.mp3

(yes, I'm posting it again)
This post has been edited by Phoebius: 23 January 2009 - 05:42 AM

#205 User is offline Chimpo 

Posted 23 January 2009 - 07:11 AM

  • Posts: 7172
  • Joined: 26-July 06
  • Gender:Not Telling
I am going to beat your ass if you post it one more time.

#206 User is offline nineko 

Posted 23 January 2009 - 09:55 AM

  • I am the Holy Cat
  • Posts: 5341
  • Joined: 17-August 06
  • Gender:Male
  • Location:italy
  • Project:I... don't even know anymore :U
  • Wiki edits:5,251
And I'm still asking what is the target format, since there hasn't been a decision yet. Each format has some features but also some downsides.

MIDI:
+: probably the most widely used format, a whole lot of people (including Tweaker) are familiar with it
+: can be speeded up and transposed in real time
+: files are tiny
+: although not part of the MIDI standard, it's easy to set up a loop point (see Sonic & Knuckles Collection)
-: not very flexible
-: their outcome is hardware depending (though most computer nowadays just stream MIDIs through the Microsoft Synthetizer)

Modules:
+: highly flexible, with a module you can recreate everything, from a chiptune, to a MIDI, to a 2612, to... whatever you want
+: can be speeded up and transposed in real time
+: support looping and jumping natively
+/-: files, while being usually bigger than MIDIs, are always much smaller than WAVs, and often smaller than MP3s
-: not everyone is familiar enough with trackers to completely use their potential. Picking module files would restrict the number of eligible composers

MP3:
+: just like module files, mp3s can sound like whatever you want, with the additional benefit that you can use any program to make them, thus giving everyone the chance to contribute songs
-: files tend to be big
-: a complex FFT algorithm is needed to indipendently alter speed and pitch
-: hard to loop

WAV:
No.

This is a start, if anyone wants to elaborate from here, feel free to.
This post has been edited by nineko: 23 January 2009 - 10:10 AM

#207 User is offline TmEE 

Posted 23 January 2009 - 10:17 AM

  • Hot music ~~~~
  • Posts: 1716
  • Joined: 06-January 08
  • Gender:Male
  • Location:Estonia, Rapla City
  • Project:Big Neighbor Disturber, Laser Raster Scan Projector
  • Wiki edits:11
I would go for modules, or perhaps OGGs when you have music that's a bit too much trouble to represent in modules. MP3 sucks.

View PostPhoebius, on Jan 23 2009, 12:40 PM, said:



Simon Stalenhag kicks @$$ :psyduck:
This post has been edited by TmEE: 23 January 2009 - 10:19 AM

#208 User is offline Slingerland 

Posted 23 January 2009 - 01:59 PM

  • Posts: 591
  • Joined: 06-January 08
  • Gender:Male
  • Location:Hollywood Hills, CA
  • Project:Hustlin' at Warner Bros.
  • Wiki edits:85
OGGs are the jam. I use 'em.

#209 User is offline Andlabs 

Posted 24 January 2009 - 06:37 PM

  • 「いっきまーす」
  • Posts: 2175
  • Joined: 11-July 08
  • Gender:Male
  • Project:Writing my own MD/Genesis sound driver :D
  • Wiki edits:7,061

View Postnineko, on Jan 23 2009, 09:55 AM, said:

And I'm still asking what is the target format, since there hasn't been a decision yet. Each format has some features but also some downsides.

MIDI:
+: probably the most widely used format, a whole lot of people (including Tweaker) are familiar with it
+: can be speeded up and transposed in real time
+: files are tiny
+: although not part of the MIDI standard, it's easy to set up a loop point (see Sonic & Knuckles Collection)
-: not very flexible
-: their outcome is hardware depending (though most computer nowadays just stream MIDIs through the Microsoft Synthetizer)

Modules:
+: highly flexible, with a module you can recreate everything, from a chiptune, to a MIDI, to a 2612, to... whatever you want
+: can be speeded up and transposed in real time
+: support looping and jumping natively
+/-: files, while being usually bigger than MIDIs, are always much smaller than WAVs, and often smaller than MP3s
-: not everyone is familiar enough with trackers to completely use their potential. Picking module files would restrict the number of eligible composers

MP3:
+: just like module files, mp3s can sound like whatever you want, with the additional benefit that you can use any program to make them, thus giving everyone the chance to contribute songs
-: files tend to be big
-: a complex FFT algorithm is needed to indipendently alter speed and pitch
-: hard to loop

WAV:
No.

This is a start, if anyone wants to elaborate from here, feel free to.

And what if someone wants to port to Sega Genesis? Or to MS-DOS? Obviously the two won't work right; Genesis can't read from any of these types, and MS-DOS needs drivers.

#210 User is offline Ritz 

Posted 24 January 2009 - 10:03 PM

  • Subhedgehog
  • Posts: 3658
  • Joined: 01-January 06
  • Gender:Not Telling
  • Location:Glimmering Cornhole Zone
  • Wiki edits:2

View PostAndlabs, on Jan 24 2009, 03:37 PM, said:

And what if someone wants to port to Sega Genesis?

Snowball's chance in hell with E02. Let's not have this discussion again!

For what it's worth, I'm vouching for modules. Sure, Nineko is the only person around here who's familiar with them, but there's no reason why you people couldn't work with the format if you actually tried. I'd never done anything music related in my life, and even I was able to wring something decent out of Modplug in half an hour.

  • 16 Pages +
  • ◄ First
  • 12
  • 13
  • 14
  • 15
  • 16
    Locked
    Locked Forum

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users