首页
社区
课程
招聘
[翻译]如何在自己的代码中播放XM音乐
发表于: 2004-8-30 09:00 6516

[翻译]如何在自己的代码中播放XM音乐

2004-8-30 09:00
6516
How to play XM Music From your own code  
=======================================

Over View
=========

Heya all,
the perefect way to play XM music is by using the MiniFmod.
since it is free to use, we can produce really cool keygens.
i'v choosed keygens as the perfect taregt to play music on,
as we all know its cool in the end.

allright, lets begine.
first we will deal with the music.
The best way to find our XM music is the mod archive located at:
http://www.modarchive.com/
it is a huge archive, and allot of cool music can be found there,
so just before coding, select ur file (recomended size : 2k-30k)
i especially like the "Hybrid Song.XM", (i first heard it in a installer
of Worms :-) ) or "trainer.XM", but i am sure there are millions of them out there.

once we choose our music, we need to dump its content!!
now, sicne this article is for Visual C++ coders, our dump
is apparently C++ style hex.
for the dumping rutine we will use Thigo's excellent Table Extractor,
located at protools/anticrack..or just google for it.

Duming Table
============

/* Dumping Hybrid Song.XM (51k) */

Load your XM file in Thigo's Table extractor,
now we need to supply few info to the program:
Address (HEX): 0
Items: Bytes
Size (Bytes) of Table(Hex): CCD4 /* File Size */
Number Of Items on a Line: 20    /* put how many you like personally i put 20 */
C/C++                            /* Dump Style Language  */
Dump to file: checked            /* [v] */

ok, we dont need anymore options filled,
Press the "Go !" button and we see our thread make an effort to dump
the Image as fast as possible ;-),
0....100%, great Table dumped in result.txt (same dir as the XM file).

Coder Point of View
===================

look at the dumped results.txt..geesh, it is very big..(300k)
yes, thats the coast of files that have 20++k and above!,
so keep in mind that since your making a keygen, the file should be
as minimal as possible, but consider the best sound u can get :-)
save this file somewhere, we need to use some source code from now on.

The MiniFmod
============

information about MiniFmod 1.6:
This small XM replay system only adds 5k to your exe! Now including FULL SOURCE CODE!!!
FEXP tool to export a header based on your song, which will be compiled into MiniFMOD and exclude whole portions of code!
Pre-buffered output for 0 latency, and high output stability
100% click free.
XM sample callbacks for user generated or compressed XM samples!
File system callbacks so you can specify whatever loading system you like! (disk/wad/memory)
Copyright 2001-2002 Firelight Technologies Pty.

The MiniFmod can be found at http://www.Fmod.org
or for quick download: http://www.fmod.org/files/minifmod160.zip
note: I dont use the GCC, so if you do, u'll have to sort things out :-)

The Tools:
==========

inside the MiniFmod package, there is a small tool called Fexp.exe,
this will be our XM effects optimizer for the dumped result.txt!!
other that, we have the *.c/*.h files that we will incldue in our program.

i have included a keygen template which will suite us for including the sound code.
that way, we will code together step by step.
ok, get the template and load the DSW into VC++ IDE.
it is a very basic keygen with 3 buttons,
Generate, Play, About.
our main goal is to make the sound be playble via the Play button,
it is later to be loaded automatiaclly when keygen starts.
ok, so we have our keygen.cpp with everything ready.

Starting to Code
================

the Sound must have an Handle, of course, that way
we can determine whenever we try to stop, reload, and even sharing
with other sound players (i.e: Winamp)

as a global variable, we start with:
FMUSIC_MODULE *mod; /* fmod music handler */
now, before we add more code, lets add to our project the minifmod
functions and main code.
make a new folder in the keygen's main folder, call it "Lib"
you can see it is also in the minifmod16.zip
copy the files from the minifmod16.zip\lib -> our lib folder
note: in the zip\lib there is 2 folders named "debug/final" don'not
copy its content!

alright, now back to our project,
in the project dir viewer, make a folder named "MiniFmod.c" (under the Source Files folder)
add all *.c files into it from our lib folder.
these files are:

1. Fmusic.c
2. Fsound.c
3. mixer_clipcopy.c
4. mixer_fpu_ramp.c
5. music_formatxm.c
6. system_file.c

now we need to add the header files (*.h),
make a new folder named "MiniFmod.h" (under the Header Files folder)
add all *.h files into the it from our lib folder + the lib file.
these files are:

1.  minifmod.h
2.  Mixer.h
3.  mixer_clipcopy.h
4.  mixer_fpu_ramp.h
5.  Music.h
6.  music_formatxm.h
7.  Sound.h
8.  system_file.h
9.  system_memory
10. xmeffects.h
11. winmm.lib    ; not an *.h file, but dont forget to add it too!!!

now, since its a keygen and using the standard minifmod source is not enough,
we will make some modifications into its code, that means some files from the original
has been slighly modifyed to suite our needs!
note: the modified files has been added to the source code, so i took of it already.

another thing we need to do is to create a new folder named "loadmusic.h"
(under the Header Files folder).
now listen carefully, remember the result.txt we have dumped ?
we will use it's hex dump as the file it self!,
rename the result.txt -> music.h (as specified in the modified files :-))
open it (be carefull, editing big files can cause a crash :-)),
now we need to edit the file a bit.

original Dump:
==============
static unsigned char table[52436] = {};

Modified Dump:
==============
#define MUSIC_LEN 4092

static unsigned char music[]=
{
};

note: the diffrences, always do this when trying to load new music into ur keygen!!!
once we finished editing and saving, we need to make a new *.h file:
open notepad and write/paste this code:

//===============================================================
#ifndef __LOADMUSIC_H__
#define __LOADMUSIC_H__

// Memory functions
unsigned int memopen(char *name);
void memclose(unsigned int handle);
int memread(void *buffer, int size, unsigned int handle);
void memseek(unsigned int handle, int pos, signed char mode);
int memtell(unsigned int handle);

void loadmusic(void); // Load music fucntion

#endif
//==============================================================

its a few addons(add on), basically we are making it easier for us to load the dumped xm
file into memory and make it playble.
save this file as loadmusic.h
finally, we add those 2 files (music.h / loadmusic.h) into the loadmusic folder.

last and not least, we need to add the loadmusic.cpp, which is of course not a part
of minifmod, as i said it is our modified code.
make a folder named "loadmusic.c" (under the Source Files fodler).
add this file (loadmusic.cpp)

allright, this fun the setup part of minifmod,
we now need to add those as #include in our main keygen.cpp

#include "loadmusic\loadmusic.h"
#include "lib\minifmod.h"
#include "lib\buffer.h"

note: if you take a look at loadmusic.cpp you can see our music.h declared there,
along with our new modified functions.

The Last Touch
==============

we have declared the handle of our fmod music rememebr?
FMUSIC_MODULE *mod;

right, all we need to do is to set the Fmod up and load the dumped xm file (music.h)
into memory and last call the play function!

at our play button id code (case IDC_PLAY:)
we add this code:

if (mod == NULL) // mod handle is free? (though it will work fine with other loaded audio devices)
{
   // We defined our music file to be loaded in loadmusic.cpp //
   //=============================================================//
   loadmusic(); // Call & set ready memory to load the music
   if(!FSOUND_Init(44100, 0)) // intialize memory for sound and format
   {  
      break;
   }
   mod = FMUSIC_LoadSong(NULL, NULL); // handle = LoadSong()
   FMUSIC_PlaySong(mod); // Play it (from memory), way cool!!
}
note: if you put this code in the WM_INITDIALOG, you will get autoplay effect when
loading the keygen!

if we want to Stop the music only thing we need to do is add new button called Stop,
choose an ID to it and use this code:

if (mod != NULL) // handle is loaded (playing)?
{
   FMUSIC_FreeSong(mod); // Free memory (handle)
   FSOUND_Close();       // Close it (stop it from playing)
   mod=NULL;             // make handle to be Free again
}

note: add same code at  WM_CLOSE msg!!

Important Tips
==============

this is the part where if u dont read it, u will get a funny results
when playing your XM file!!

/* from Firelight's readme */

Making your exe even smaller with XMEFFECTS.H and FEXP.EXE:
- Note all the effects in the xm replay code are wrapped with #ifdef's.  They are defined in
  xmeffects.h.
- Have a look in the zip/lib directory .. There is an executable called FEXP.EXE
- Use FEXP.EXE on an xm file and it will generate xmeffects.h for you!
- Recompile the minifmod library with the new xmeffects.h
- See your exe size go down AGAIN!
- (only play the song you fexp'ed or it will screw up on other songs probably :) ..)

yup, this mean, we make a new xmeffects.h for each music file we dump!!
else as said, we have a screwed up music :-)
-> fexp Hybrid_Song.XM -> xmeffects.h

overwrite the old xmeffects.h in our keygen\lib\ folder, and recompile our source code,
see your music plays fine.

some little note is that the minifmod abit looses the quality of the music,
well this is understandble since minifmod is not a part of the fmod library, so
it does miss some important stuff, but hey, nothing is perfect!!
for me, it rox to have cool sound in keygens, and now you guys too.

Ending
======

well,this complete the essay,
the best way to learn from it is by using the files included in the compiled keygen,
that way u can always have this as a base keygen.

MiniFmod is coded by FireLight (r)
Keygen source code + music coded by Ben & [Goofy] of FreeStylerS 2002

greets to all RCE members, and the REA community!

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 1
支持
分享
最新回复 (3)
雪    币: 323
活跃值: (589)
能力值: ( LV12,RANK:450 )
在线值:
发帖
回帖
粉丝
2
如何在自己的代码中播放XM音乐
============================

总括
====
嘿,各位好。播放XM音乐最完美的方式就是使用MiniFmod。它免费使用,我们用它可以做出十分酷的注册机。我选择注册机作为播放音乐的完美目标,因为我们最终都会知道它的酷。

好吧,我们开始吧。
首先,我们要处理一下音乐。找到我们要的XM音乐的最好途径是http://www.modarchive.com/网站上的mod 档案库(mod archive)。这是个巨大的档案库,可以找到大量的酷音乐。所以在编码前选择你的音乐文件(推荐2k-30k)。我特别喜欢"Hybrid Song.XM"(我在Worms的安装文件上第一次听到它)或"trainer.XM",但我确信那儿还有成千上万的好音乐。

一旦我们选好音乐,我们要抓取(dump)它的内容!!现在,由于本文是针对Visual c++编码人员,所以我们抓取的就是C++格式的十六进制文件。对于抓取文件的转换(dumping rutine),我们将使用Thigo的优秀的Table Extractor,位于protools/anticrack..或在google上找。

抓取表(Dumping Table)
=====================

/* Dumping Hybrid Song.XM (51k) */

用Thigo的Table extractor加载你的XM文件,现在我们需要提供一点信息给程序:
地址(十六进制):0                        (Address(hex): 0)
项目:Bytes                             (Items:Bytes)
表(十六进制)的大小(Bytes): CCD4         /文件大小/   Size (Bytes) of Table(Hex): CCD4 /* File Size */
每条线上项目数:20    /输入多少由你喜欢,我个人是20/               
                                        Number Of Items on a Line: 20    /* put how many you like personally i put 20 */
C/C++  /抓取所用的语言风格/                 C/C++          /* Dump Style Language  */
抓取到文件:勾选                            Dump to file: checked            /* [v] */

好,我们不再需要填充选项了。按“开始”按钮,我们看到程序正努力尽可能快的的抓取映像文件。:-),0....100%,完美的表(Table)抓取到result.txt(与XM文件在同一目录)。

编码者的观点
============

看看抓到的results.txt..天哪,十分的大..(300k)。是的,那就是20多K以上大的文件的界限(coast)了。所以请记住,因为你是在做注册机,文件应该尽可能的小,但考虑那是你能得到的最好声音。把文件保存到某个地方,现在我们需要利用一些源码。

MiniFmod
========

关于MiniFmod 1.6:
这个小小的XM播放系统仅增加5k到exe中!现在包括了全部源代码!!!FDXP工具输出一个基于你的音乐的头,它将被编译到MiniFmod而不是整个代码部分。
预先缓冲输出保证0延迟,高输出稳定性保证100%自由点击。(Pre-buffered output for 0 latency, and high output stability 100% click free.)
XM例子回调用户生成或压缩的XM例子!
文件系统回调以便你能确定你喜欢的任何载入系统(磁盘/wad/内存)
Copyright 2001-2002 Firelight Technologies Pty.

可以在:http://www.Fmod.org找到MiniFmod或快速下载http://www.fmod.org/files/minifmod160.zip
注意:我不用GCC,所以如果你用,请自己解决。

工具
=======

在MiniFmod包内,有一个叫Fexp.exe的小工具。它是我们对抓取的result.txt的XM效果优化器。此外,还有将包含到我们程序里的*.c/*.h文件。

我已经将注册机模板打包,里面有源码,满足了我们的需要。这样,我们就可以一步一步的编码了。好,找到模板,用VC++ IDE打开DSW。这是一个最基本的注册机,有3个按钮--“生成generate,播放play,关于about”。我们的主要目标是通过play按钮就能播放声音。好,我们让keygen.cpp和其他文件做好了准备。

开始编码
=========
当然,声音必须有一个句柄,这样我们就能决定何时停止、重新播放甚至与其他声音播放器(如Winamp)共享。
作为全局变量,我们开始于:
FMUSIC_MODULE *mod;  /* fmod music handler */
现在,在增加更多代码前,我们将minifmod函数和主要代码增加到工程里,在注册机的主文件夹建立一新的文件夹,取名“lib”,在minifmod16.zip里也可以找到它。将minifmod.zip\lib拷到lib文件夹里面。
注意:在minifmod.zip\lib里有2个名为“dubug和final”的文件夹,不要拷它们。

好了,现在回到我们的工程。在工程里新建一个名为MiniFmod.c的文件夹(就在源文件文件夹里面),把所有的*.c文件从lib文件夹里增加到里面去。这些文件是:
1. Fmusic.c
2. Fsound.c
3. mixer_clipcopy.c
4. mixer_fpu_ramp.c
5. music_formatxm.c
6. system_file.c

现在我们要增加头文件(*.h),新建一名为MiniFmod.h的文件夹(就在头文件文件夹里面),把所有的*.h文件从lib文件夹添加到里面。
1.  minifmod.h
2.  Mixer.h
3.  mixer_clipcopy.h
4.  mixer_fpu_ramp.h
5.  Music.h
6.  music_formatxm.h
7.  Sound.h
8.  system_file.h
9.  system_memory
10. xmeffects.h
11. winmm.lib    ;不是一个头文件,但不要忘记添加它   not an *.h file, but dont forget to add it too!!!

现在,由于它是个注册机,使用标准的minifmod源文件还不够,我们将对代码作些修改。这就是说,一些原始文件将做轻微修改以满足我们的需要。
注意:修改文件已经增加到源代码中了,所以我已经使用了它。

我们要做的另一件事是创建一个名为loadmisic.h的新文件夹(就在头文件文件夹里面)。现在听仔细了,记得我们抓取的result.txt吗?我们用它的十六进制抓取文件作为文件本身,改名result.txt为music.h(在修改文件里确定的 :-))。打开(仔细点,编辑大的文件会造成蹦溃。)现在我们需要对文件做点编辑。

原始抓取文件
============
static unsigned char table[52436] = {};

修改的抓取文件
==============
#define MUSIC_LEN 4092

static unsigned char music[]=
{
};

注意:当试图加载新的音乐到你的注册机里时,这些区别总是要做的(the diffrences, always do this when trying to load new music into ur keygen!!!)。一旦完成编辑并保存,我们需要新建一个*.h文件:
打开记事本,写或粘贴如下代码:
//===============================================================
#ifndef __LOADMUSIC_H__
#define __LOADMUSIC_H__

// Memory functions
unsigned int memopen(char *name);
void memclose(unsigned int handle);
int memread(void *buffer, int size, unsigned int handle);
void memseek(unsigned int handle, int pos, signed char mode);
int memtell(unsigned int handle);

void loadmusic(void); // Load music fucntion

#endif
//==============================================================

这些是另外加上去的,基本上使我们更容易加载抓取的XM文件到内存中执行。保存这个文件为loadmusic.h。最后,我们增加music.h 和loadmusic.h到loadmusic.h文件夹里。

最后,但并非至少,我们需要增加loadmusic.cpp,它当然不是minifmod的一部分,正如我所说的,它是我们修改的代码。
新建一名为loadmusic.c的文件夹(就在源文件Source Files文件夹下面),增加这个文件(loadmusic.cpp)。

好了,有意思的是minifmod的安装部分。
我们现在需要将那些#define增加到keygen.cpp

#include "loadmusic\loadmusic.h"
#include "lib\minifmod.h"
#include "lib\buffer.h"                    //译者注:在源码包里我好像没找到这个文件哦!!好像也没什么影响!

注意:如果你看看loadmusic.cpp,你就能看见music.h以及我们新修改的函数在那里有声明。

最后的接触
==========

我们已经声明fmod music的句柄,记得吗?
FMUSIC_MODULE *mod;

好,我们所要做的就是设置Fmod并加载抓取的XM文件(music.h)到内存,并调用play函数。

在play按钮id code(case IDC_PLAY:),增加下列代码:

if (mod == NULL) // mod handle is free? (though it will work fine with other loaded audio devices)
{
   // We defined our music file to be loaded in loadmusic.cpp //
   //=============================================================//
   loadmusic(); // Call & set ready memory to load the music
   if(!FSOUND_Init(44100, 0)) // intialize memory for sound and format
   {  
      break;
   }
   mod = FMUSIC_LoadSong(NULL, NULL); // handle = LoadSong()
   FMUSIC_PlaySong(mod); // Play it (from memory), way cool!!
}

注意:如果你将这段代码放在WM_INITDIALOG,在加载注册机时会有自动播放效果。

如果要停止音乐,我们只要新增一个Stop按钮,对它选个ID,并使用下列代码:

if (mod != NULL) // handle is loaded (playing)?
{
   FMUSIC_FreeSong(mod); // Free memory (handle)
   FSOUND_Close();       // Close it (stop it from playing)
   mod=NULL;             // make handle to be Free again
}

注意:在WM_CLOSE增加同样的代码

重要的技巧
==========

这部分如果你没有阅读过,你会在播放XM文件时获得一个有趣的结果。

/* from Firelight's readme */

利用XMEFFECTS.H 和 FEXP.EXE使EXE更小
--注意所有的XM重播代码效果打包在 #ifdef。它们在xmeffects.h中有定义。
--看看zip/lib目录,里面有FEXP.EXE
--用FEXP.EXE对一个XM文件处理,会得到xmeffects.h
--用新的xmeffects.h重新编译minifmod 库
--你的EXE大小再次降下来了。
--(仅播放你用FEXP处理的音乐,可能会激活其他的音乐 :)..)

这就是说,对每个抓取的音乐文件用一个新的xmeffects.h,否则,如前所说 ,会引发别的音乐。 因为fexp Hybrid_Song.XM -> xmeffects.h

覆盖keygen\lib\folder里面的旧xmeffets.h,重新编译源码,音乐正常播放了。

一些小注意:minifmod会使音质有点小的松散,这是可理解的。因为minifmod并非fmod库的一部分,所以它会丢失一些重要的东东,但是,没有什么事是完美的。对我而言,注册机中的音乐是很酷的,你们的也是。

结束
====

好的,现在结束本文,从本文学习 的最好方法就是使用包含在已编译注册机里的文件,这样你总可以把它作为一个基本注册机。

MiniFmod 由FireLight编码
Keygen source code + music由Ben & [Goofy] of FreeStylerS 2002年编译。

感谢 所有的RCE成员,以及REA社区。

                                      springkang[DFCG][NSSG][TT]
                                                     译于2004.08.29 凌晨 0:30
2004-8-30 09:01
0
雪    币: 323
活跃值: (589)
能力值: ( LV12,RANK:450 )
在线值:
发帖
回帖
粉丝
3
这是附件,里面有源码包和译文等。
请各位兄弟帮忙看看,有没有译错的地方!附件:fy.rar
2004-8-30 09:03
0
雪    币: 392
活跃值: (909)
能力值: ( LV9,RANK:690 )
在线值:
发帖
回帖
粉丝
4
不错,支持,不过这个办法麻烦了一些,DFCG LeNgHoSt的KeyGen模板更好:)
2004-8-30 12:03
0
游客
登录 | 注册 方可回帖
返回
//