📜 ⬆️ ⬇️

Tracker music. We join the great

I present to your attention a selection of 15 of my favorite V2M-songs from comrades Farbrausch . To listen enough to run Exe-shnik. Pay attention to its size and sound quality!

narod.ru/disk/9788383000/q.exe.html

(This is not a virus, I swear by karma, I personally compiled it myself)
')
Immediately make a reservation, it does not work in Vista and Windows 7 , why I don’t know why = (because I don’t use the full profane in system programming, if someone tells you why, I’m grateful. In * nix under Wine should work.

Before you start the story I recommend refreshing these habratopiki

Music. The code inside. Razor 1911, Farbrausch ...
Demos The art of programming.

As it so happened, I was carried away with all sorts of tracker melodies.
I had a lecturer at the university (on the complex exchange of technological experiments) who liked to philosophize about the connection between music and mathematics at lectures, and quite interesting, I must say. And, in my opinion, tracker music is the music that is closest to mathematics.

For the unenlightened, I’ll say that this is music played in cracks / keygens, many computer games, demoscenter videos ... To tell the truth, I really don’t understand why, for example, midi-melodies are so firmly rooted in mobile phones, because the tracker music weighs about that much but it sounds much better. There are a lot of tracker Mouzon formats: .mod, .it, .xm, .s3m, ..., etc. Their main feature is a very small “weight” (tens to hundreds of kilobytes, although it depends on the bitness of the samples, there may be megabytes), while the sound is beautiful (compared to midi-muzon, and IMHO, just beautiful). More detailed information can be easily found on the vast expanses of the Internet.

Distract again and give a link to other “very-best” tracker tracks: http://websound.ru/tracked-music.htm (and generally recommend this site about music websound.ru in every possible way). I only convincingly listen to them not through Winamp (and he can), but through XMPlay - in my experience - the most adequate reproduction of modules.

The guys from Farbrausch (represented by kb ) went further and created their own music engine v2 . The music created in it sounds in amazing demos of this demo maker group. Actually, I suspect there is not so much v2m music in nature (if wrong, correct, I will be pleasantly surprised and grateful), but what can be downloaded, for example, here (about 200 amazingly sounding melodies of only 1 MB in size) I recommend playing the in_v2m.dll plugin for Winamp from here (because it seems that the new version 1.5 of the plug-in, available on the author's site , I lost some v2m-ki incorrectly). The difference of this format from the classic tracker melodies is that it does not use samples at all, and all tools and effects, including voice synthesis, are programmatically generated by the engine.

Well, I wanted to “join the great one” a little bit and try to mix an executable with a musician, firstly to find out how these geniuses-demostseners achieve such tiny sizes of demos, and secondly just to share their favorite v2m-compositions with you .

I took the tinyplayer.cpp file as the basis for an example of using the API ( from here ). It was a source for playing one music that was compiled into it directly in a code like this:

const unsigned char theTune[] = {
0xe0, 0x01, 0x00, 0x00, 0xd7, 0x84, 0x02, ...


connected in the .h file. I had to create a similar .h file with the compositions I needed.

I copied the necessary v2m files to a folder, created a gen_tunes.py script in it:

import glob

out = open( 'tune1.h' , 'w' )
listOut = open( 'list.txt' , 'w' )

def writeTune(i, data):
out .write( '\nconst unsigned char tune_%s[] = {\n\t' % i)

t = 0

lst = []
for b in data:
lst.append(hex(ord(b)))
t+=1
if t % 16 == 0:
lst[-1] += '\n\t'

out .write( ', ' .join(lst))
out .write( '};\n\n' )

def main():
i = 0

for fn in glob.glob( '*.v2m' ):
f = open(fn, 'rb' )
data = f.read()

writeTune(i, data)
listOut.write( "%s, %s\n" % (i, fn))

i += 1

main()


* This source code was highlighted with Source Code Highlighter .


and running it, got the file tune1.h "weight" 7.84 MB, the total weight of the .v2m files was 1.46 MB.

And as I said, tinyplayer.cpp was added as follows:

//
// tinyplayer: An example for using libv2 and a lesson in getting
// Win32 executables small. Written by Tammo "kb"
// Hinrichs in 2004. This file (as well as the .sln
// and the .vcproj file) is in the public domain,
// do with it what you want.
//
// farbrausch consumer consulting, Dec. 2004
//

// it is advised to look into the compiler settings to see why the
// final exe takes only 52k (or 12.5k after being packed with an
// executable packer)

// we need: windows...
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

// ... the libv2 ...
#include "libv2.h"

// ... and our tune.
//#include "tune.h"
#include "tune1.h"

// --------------------------------------------------------------------------------

// a few fakes coming up because this gets compiled without any stdlib and so
// we don't even have printf() :

static HANDLE stdout;

static void print( const char *text)
{
unsigned long bw;
int len=0;
while (text[len]) len++; // yeah, strlen() also is a luxury. :)
WriteFile(stdout,text,len,&bw,0);
}

static const char * digits[]={ "0" , "1" , "2" , "3" , "4" , "5" , "6" , "7" , "8" , "9" };
static void print( long num) {
int nums[20];
int n = 0;

if (num == 0) {
print( "0" );
}

while (num != 0) {
nums[n++] = num % 10;
num = num / 10;
};
n--;

for ( int nn=n;nn>=0;nn--) {
print(digits[nums[nn]]);
}
}

// VC needs this symbol as soon as something uses floating point numbers
// (and libv2 does):
extern "C" int _fltused;
int _fltused;

// --------------------------------------------------------------------------------
const char * songs[] = {
"acid in space" ,
"agony remix" ,
"breeze" ,
"chiptown" ,
"cracked zone" ,
"fr-014 garbage collection - main" ,
"fr-037 the code inside" ,
"full access" ,
"gamma projection" ,
"josie3" ,
"multiscenist" ,
"trance style" ,
"ultra short" ,
"welcome to vectronix disco" ,
"zuibath"
};

long songDurations[] = { // in sec
233,
296,
181,
157,
267,
128,
211,
225,
152,
207,
177,
465,
186,
208,
170
};

const unsigned char * songData[] = {
tune_0,tune_1,tune_2,tune_3,tune_4,tune_5,tune_6,tune_7,
tune_8,tune_9,tune_10,tune_11,tune_12,tune_13,tune_14
};

static void writeSongLine( int current) {
print(current+1);print( " - " );print(songs[current]);print( " (" );
long duration = songDurations[current];
print(duration/60); // min
print( ":" );
long sec = duration%60;
if (sec<10)
print( "0" );
print(sec);
print( ")" );
}

static void playSong( int current) {
print( "\r \r" );
writeSongLine(current);
ssStop();
ssClose();
ssInit(songData[current],GetForegroundWindow());
ssPlay();
}

int SONG_NUM_MAX = 14;

int main( int argc, char *argv[])
{
// we need this for print() to work
stdout=GetStdHandle(STD_OUTPUT_HANDLE);

// print a bunch of senseless info..
print( "Farbrausch Tiny Music Player v0.2\n" );
print( "Code and Synthesizer (C) 2000-2004 kb/Farbrausch\n" );

print( "Compiled by: Xonix\n\n" );

print( "Tunes:\n\n" );

for ( int i=0; i<=SONG_NUM_MAX; i++) {
writeSongLine(i);
print( "\n" );
}

print( "\n\n" );

int current = 0;

print( "Now playing (ESC to quit, UP/DOWN to select):\n" );
playSong(current);

for ( ; ; ) {
if ( GetAsyncKeyState ( VK_ESCAPE ) != 0 )
break ;
else if ( GetAsyncKeyState ( VK_UP ) != 0 ) {
if (current > 0)
current--;
else
current = SONG_NUM_MAX;

playSong(current);

while (GetAsyncKeyState ( VK_UP ) != 0) {Sleep(10);}
}
else if ( GetAsyncKeyState ( VK_DOWN ) != 0 ) {
if (current < SONG_NUM_MAX)
current++;
else
current = 0;

playSong(current);

while (GetAsyncKeyState ( VK_DOWN ) != 0) {Sleep(10);}
}

if (ssGetTime() > (songDurations[current] + 1) * 1000) { // song ended
if (current < SONG_NUM_MAX)
current++;
else
current = 0;

playSong(current);
}
Sleep ( 10 );
}

// stop and deinit the player
ssStop();
ssClose();

// ... and we're done.
ExitProcess(0);
}


* This source code was highlighted with Source Code Highlighter .


I draw your attention that the program uses only windows.h (besides, in fact, libv2.h and tune1.h), and nothing more (all for the compactness of the resulting .exe, so we have to write the print and formatting with our own hand).

For compilation I used, strangely enough, QtCreator + Mingw, for Visual Studio, forgive, did not master (I like it when everything is clear, that is, I see what starts when compiling, etc.).

Here I draw the attention of comrades who have reached for the "-" button, that this is probably the first, consciously compiled by me C ++ code =)

The project looked like this:
# -------------------------------------------------
# Project created by QtCreator 2009-06-10T03:58:51
# -------------------------------------------------
QT -= core \
gui
TARGET = v2m_palyer_qt
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += main.cpp
HEADERS += tune.h tune1.h \
libv2.h
OTHER_FILES +=
LIBS += -L"C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\Lib" \
-L"D:/TEST/v2m/libv2_1.0/v2m_palyer_qt" -llibv2 -ldsound -luser32 -lkernel32


As a result of the compilation we get the file v2m_palyer_qt.exe. But that is not all ). Now we need to "shrink" this file. For this, I used the usual executables compressor upx for such tasks with the --best setting, which shrank my executable from 1.48 MB to 72 KB.

I also tried beroexepacker - I squeezed better, but I stopped at the first option, because Antiviruses know upx and are able to unpack it in search of viruses, and after this comrade they do not know how.

Finally, I tried the “grouper” kkrunchy - it was the guys from Farbrausch who used it, and he really stung to exactly 64,000 bytes, but at the same time the exe-shnik started for a long time.

Among the shortcomings: ekzeshnik uses global hooks for browsing / exit. How to do otherwise - I do not know, and the author of kb left a comment on this
// yep, I know this will stop even if we don't have focus. I simply don't care.
I also did not bother.

Thanks for attention.

Source: https://habr.com/ru/post/66585/


All Articles