Представляю вашему вниманию подборку из 15 моих любимых V2M-композиций от товарищей Farbrausch. Для прослушивания достаточно запустить Exe-шник. Обращаем внимание на его размер и на качество звучания!
narod.ru/disk/9788383000/q.exe.html
(Это не вирус, клянусь кармой, сам лично компилил)
Сразу оговорюсь, не работает в Висте и Windows 7, почему — не знаю =(, т.к. не использую и полный профан в системном программировании, если кто подскажет, почему — буду благодарен. В *nix под Wine должно работать.
Прежде чем начать повествование рекомендую освежить в памяти эти хабратопики
Music. The code inside. Razor 1911, Farbrausch…
Деморолики. Искусство программирования.
Как то так случилось, что я увлекся всякими трекерными мелодиями.
У меня в универе был лектор (по ТФКП), который любил на лекциях пофилософствовать о связи музыки и математики, и довольно интересно, надо сказать. И, по-моему, трекерная музыка — это именно та музыка, которая ближе всего находится к математике.
Для непосвещенных скажу, что это музыка, звучащая в кряках/кейгенах, многих компьютерных играх, демосценерских роликах… По правде сказать, я искренне не понимаю, почему, например, именно midi-мелодии так прочно укоренились в мобильниках, ведь трекерная музычка весит примерно столько же, а звучит гораздо лучше. Форматов трекерного музона очень много: .mod, .it, .xm, .s3m, ..., и т.д. Основная их особенность — очень малый «вес» (десятки-сотни килобайт, хотя зависит от битности семплов, могут быть и мегабайты), при этом красивое (по сравнению с миди-музоном, а, имхо, и просто красивое) звучание. Более подробную информацию можно с легкостью отыскать на бескрайних просторах интернета.
Опять отвлекусь и дам ссылку на другие «самые-самые» трекерные композиции: http://websound.ru/tracked-music.htm (и вообще всячески рекомендую этот сайт о музыке websound.ru). Только убедительно заклинаю слушать их не через Winamp (а он может), а через XMPlay — по моему опыту — самое адекватное воспроизведение модулей.
Ребята из Farbrausch (в лице kb) пошли дальше и создали свой музыкальный движок v2. Музыка, созданная в нем и звучит в потрясающих демках этого демомейкерского коллектива. Собственно, я подозреваю, самой v2m-музыки в природе существует не так много (если неправ — поправьте, буду приятно удивлен и благодарен), но то что есть можно скачать, например, тут (около 200 изумительно звучащих мелодий размером всего 1 Мб) для проигрывания рекомендую in_v2m.dll плагин для винампа отсюда (т.к. сдается, что новая версия 1.5 плагина, доступная на авторском сайте у меня проигрывала некоторые v2m-ки некорректно). Отличие этого формата от классических трекерных мелодий в том, что в нем совершенно не используются семплы, а все инструменты и эффекты, включая синтез голоса, программно генерируются движком.
Ну и вот мне захотелось немножко «приобщиться к великому» и попробовать скомпилять экзешник с музычкой, во-первых чтоб узнать, как же эти гении-демосценеры добиваются таких крошечных размеров демок, а во-вторых просто чтоб поделиться с вами своими любимыми v2m-композициями.
Я взял за основу файлик tinyplayer.cpp приведенный как пример использования API (отсюда). Он представлял собой исходник проигрывания одной музычки, которая вкомпилировалась в него прямо в коде типа такого:
подключаемом в .h файле. Мне надо было создать аналогичный .h-файл но с нужными мне композициями.
Скопировал нужные v2m-ки в папку, создал там скриптик gen_tunes.py содержанием:
и запустив его, получил файл tune1.h «весом» 7.84 Мб, суммарный вес файликов .v2m же был 1.46 Мб.
И как я уже говорил, tinyplayer.cpp был дополнен следующим образом:
Обращаю ваше внимание, что в программе используется только windows.h (помимо, собственно, libv2.h и tune1.h), и ничего более (все для компактности получаемого .exe, поэтому print и форматирование мы вынуждены писать собственноручно).
Для компиляции использовал как ни странно QtCreator + Mingw, ибо Visual Studio, простите, не осилил (люблю когда все явно, т.е. я вижу что запускается при компиляции и т.д.).
Тут обращаю внимание товарищей, потянувшихся к кнопочке "-", что это пожалуй первый, осознанно скомпиленный мною C++ код =)
Проект выглядел так:
В результате компиляции получаем файлик v2m_palyer_qt.exe. Но это еще не все ). Теперь надо «ужать» этот файлик. Для этого я использовал обычный для таких задач executables compressor upx с настройкой --best, ужавший мой экзешник с 1.48 Мб до 72 Кб.
Так же пробовал beroexepacker — ужал лучше, но остановился на первом варианте, т.к. антивирусы знают upx и умеют его распаковывать в поисках вирусов, а после этого товарища — не умеют.
И наконец пробовал «ужиматор» kkrunchy — именно им пользуются сами ребята из Farbrausch, и действительно он ужал ровнехонько до 64000 байт, но при этом exe-шник ну ооооочень долго стартовал.
Из недостатков: екзешник использует глобальные хуки для перелистывания/выхода. Как сделать иначе — не знаю, а автор kb по этому поводу оставил комментарий
я тоже не стал заморачиваться.
Спасибо за внимание.
narod.ru/disk/9788383000/q.exe.html
(Это не вирус, клянусь кармой, сам лично компилил)
Сразу оговорюсь, не работает в Висте и Windows 7, почему — не знаю =(, т.к. не использую и полный профан в системном программировании, если кто подскажет, почему — буду благодарен. В *nix под Wine должно работать.
Прежде чем начать повествование рекомендую освежить в памяти эти хабратопики
Music. The code inside. Razor 1911, Farbrausch…
Деморолики. Искусство программирования.
Как то так случилось, что я увлекся всякими трекерными мелодиями.
У меня в универе был лектор (по ТФКП), который любил на лекциях пофилософствовать о связи музыки и математики, и довольно интересно, надо сказать. И, по-моему, трекерная музыка — это именно та музыка, которая ближе всего находится к математике.
Для непосвещенных скажу, что это музыка, звучащая в кряках/кейгенах, многих компьютерных играх, демосценерских роликах… По правде сказать, я искренне не понимаю, почему, например, именно midi-мелодии так прочно укоренились в мобильниках, ведь трекерная музычка весит примерно столько же, а звучит гораздо лучше. Форматов трекерного музона очень много: .mod, .it, .xm, .s3m, ..., и т.д. Основная их особенность — очень малый «вес» (десятки-сотни килобайт, хотя зависит от битности семплов, могут быть и мегабайты), при этом красивое (по сравнению с миди-музоном, а, имхо, и просто красивое) звучание. Более подробную информацию можно с легкостью отыскать на бескрайних просторах интернета.
Опять отвлекусь и дам ссылку на другие «самые-самые» трекерные композиции: http://websound.ru/tracked-music.htm (и вообще всячески рекомендую этот сайт о музыке websound.ru). Только убедительно заклинаю слушать их не через Winamp (а он может), а через XMPlay — по моему опыту — самое адекватное воспроизведение модулей.
Ребята из Farbrausch (в лице kb) пошли дальше и создали свой музыкальный движок v2. Музыка, созданная в нем и звучит в потрясающих демках этого демомейкерского коллектива. Собственно, я подозреваю, самой v2m-музыки в природе существует не так много (если неправ — поправьте, буду приятно удивлен и благодарен), но то что есть можно скачать, например, тут (около 200 изумительно звучащих мелодий размером всего 1 Мб) для проигрывания рекомендую in_v2m.dll плагин для винампа отсюда (т.к. сдается, что новая версия 1.5 плагина, доступная на авторском сайте у меня проигрывала некоторые v2m-ки некорректно). Отличие этого формата от классических трекерных мелодий в том, что в нем совершенно не используются семплы, а все инструменты и эффекты, включая синтез голоса, программно генерируются движком.
Ну и вот мне захотелось немножко «приобщиться к великому» и попробовать скомпилять экзешник с музычкой, во-первых чтоб узнать, как же эти гении-демосценеры добиваются таких крошечных размеров демок, а во-вторых просто чтоб поделиться с вами своими любимыми v2m-композициями.
Я взял за основу файлик tinyplayer.cpp приведенный как пример использования API (отсюда). Он представлял собой исходник проигрывания одной музычки, которая вкомпилировалась в него прямо в коде типа такого:
const unsigned char theTune[] = {
0xe0, 0x01, 0x00, 0x00, 0xd7, 0x84, 0x02, ...
подключаемом в .h файле. Мне надо было создать аналогичный .h-файл но с нужными мне композициями.
Скопировал нужные v2m-ки в папку, создал там скриптик gen_tunes.py содержанием:
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.
и запустив его, получил файл tune1.h «весом» 7.84 Мб, суммарный вес файликов .v2m же был 1.46 Мб.
И как я уже говорил, tinyplayer.cpp был дополнен следующим образом:
//
// 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.
Обращаю ваше внимание, что в программе используется только windows.h (помимо, собственно, libv2.h и tune1.h), и ничего более (все для компактности получаемого .exe, поэтому print и форматирование мы вынуждены писать собственноручно).
Для компиляции использовал как ни странно QtCreator + Mingw, ибо Visual Studio, простите, не осилил (люблю когда все явно, т.е. я вижу что запускается при компиляции и т.д.).
Тут обращаю внимание товарищей, потянувшихся к кнопочке "-", что это пожалуй первый, осознанно скомпиленный мною C++ код =)
Проект выглядел так:
# -------------------------------------------------
# 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
В результате компиляции получаем файлик v2m_palyer_qt.exe. Но это еще не все ). Теперь надо «ужать» этот файлик. Для этого я использовал обычный для таких задач executables compressor upx с настройкой --best, ужавший мой экзешник с 1.48 Мб до 72 Кб.
Так же пробовал beroexepacker — ужал лучше, но остановился на первом варианте, т.к. антивирусы знают upx и умеют его распаковывать в поисках вирусов, а после этого товарища — не умеют.
И наконец пробовал «ужиматор» kkrunchy — именно им пользуются сами ребята из Farbrausch, и действительно он ужал ровнехонько до 64000 байт, но при этом exe-шник ну ооооочень долго стартовал.
Из недостатков: екзешник использует глобальные хуки для перелистывания/выхода. Как сделать иначе — не знаю, а автор kb по этому поводу оставил комментарий
// yep, I know this will stop even if we don't have focus. I simply don't care.
я тоже не стал заморачиваться.
Спасибо за внимание.