[xiph-cvs] cvs commit: ogg-tools/oggmerge/tools Makefile.am midimerge.c
Jack Moffitt
jack at xiph.org
Mon Sep 3 16:46:31 PDT 2001
jack 01/09/03 16:46:30
Modified: oggmerge Makefile.am configure.in oggmerge.c
Added: oggmerge/testfiles Makefile.am fire6.mng
oggmerge/tools Makefile.am midimerge.c
Removed: oggmerge fire6.mng
Log:
Moved testfiles into ./testfiles
Added tools directory and the midimerge tool.
midimerge converts type 1 midifiles into type 0, and expands their running
status. All midi files must be processed with this _before_ oggmerge
will deal properly with them.
Revision Changes Path
1.3 +2 -0 ogg-tools/oggmerge/Makefile.am
Index: Makefile.am
===================================================================
RCS file: /usr/local/cvsroot/ogg-tools/oggmerge/Makefile.am,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- Makefile.am 2001/09/03 23:27:01 1.2
+++ Makefile.am 2001/09/03 23:46:29 1.3
@@ -2,6 +2,8 @@
AUTOMAKE_OPTIONS = dist-zip foreign
+SUBDIRS = testfiles tools
+
bin_PROGRAMS = oggmerge
oggmerge_SOURCES = oggmerge.c vorbis.c midi.c\
1.3 +1 -1 ogg-tools/oggmerge/configure.in
Index: configure.in
===================================================================
RCS file: /usr/local/cvsroot/ogg-tools/oggmerge/configure.in,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- configure.in 2001/09/03 23:27:01 1.2
+++ configure.in 2001/09/03 23:46:29 1.3
@@ -17,4 +17,4 @@
AC_HEADER_STDC()
#AC_CHECK_HEADERS(libmng.h)
-AC_OUTPUT(Makefile)
+AC_OUTPUT(Makefile testfiles/Makefile tools/Makefile)
1.3 +1 -1 ogg-tools/oggmerge/oggmerge.c
Index: oggmerge.c
===================================================================
RCS file: /usr/local/cvsroot/ogg-tools/oggmerge/oggmerge.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- oggmerge.c 2001/09/03 23:27:01 1.2
+++ oggmerge.c 2001/09/03 23:46:29 1.3
@@ -25,7 +25,7 @@
#include "vorbis.h"
#include "midi.h"
-#define VERSIONINFO "oggmerge v0.9\n"
+#define VERSIONINFO "oggmerge v" VERSION "\n"
param_t params;
1.1 ogg-tools/oggmerge/testfiles/Makefile.am
Index: Makefile.am
===================================================================
## process this file with automake to produce Makefile.in
AUTOMAKE_OPTIONS = foreign
EXTRA_DIST = fire6.mng
1.1 ogg-tools/oggmerge/testfiles/fire6.mng
Index: fire6.mng
===================================================================
MNG
TERM
²óVê7ueìÉPÑ#Ü/ «4ÓÌ¿ üää=znZ7ôÜûp¶
¶\ ï
g_«ÿÂàÔ:æs· .[EOcJJçÜÇÞ'6MJkZ¾Å:
fù8iSÆ®½¬`ì*g=¹¤Òà
¢£©ÜÚ´©¬#CÁúqÎ <¥%ôAúIÕ¶9¥â¤ Î>1F]Á â¨\à
,|Ù§ô
¡FåÀbà
J·5ÌTÁø
1$©ëm
xÚ¯ÒKú©µñFZRNóP°efVʯKE8?gã6uþ«elwÅëB¬¼Ô9Äå7àÇí§mÃ;2òJ¯ÃÑ»R=ñ®p®7<GÖü?£¹¬ö~ÃÃÉø¸TÉSå<Ôï·ENÄÇëÑ}ý6@Âçþ}üÿðÞcf!
Å{¸
xºÇëñq`û?%~ñ/þ/ñÁúöã·Ö¯zãÆH\Ü°ùBîðp_t½tñ?iÂuõhÄ12d¤Îý
9gðíyfG¹èâm©Õz\4@
xKõØW¼-=|8{`9æì]õMÑ{¥¼w\Hm-:Õu1Æ®3ƨn62`Ó]_³1]TÑbl«Rsgfx¹p%4·<«ÚÐF
~)7ò¹·ÐèÝdÛ*JlDK
pïflÊCý@'¶òÒ¶f}éi)5((¶l,tÒ+#%Ã\c:ȹZݲquØÁ%°Â¹çl ÉûÁiÉÓ`½ô½?«Y=\2<«àï
}ïg}ûÅÞÅÿíßaÿî~òýEÊxÉGÞ¦
ÔÕÖL)àJúX£YÈjÉåkäÙ»Ö]ns£ÎݶF¡Tëø°x^ê"êÐ1åþ[hèjå&x{ëßWwQÖßú»¾Ý_ ÷í
<ãqÁ2Iü8¢E-±ó$öÆrÆÔB**+pQ)ÆNu`
ÛJr^ááC£mÛ³T»u]c{q£
¸çÂ"wncàèGÖâ8xå\auïÕã¿öÌ~)ÒÀì=t¯ÖyÆWÄâ fìÉ.»º¨.˸¨>¸òa$Ä$f¥SÇXlÄ8¢ÖzN
§½çze
0cWù0er3¸Æw¯1ÏÁ=õ¤sLí뼩ízvó,fíwyãÓ½Öóà qæ#
©y})\åõ·zjÑ{lZ×¢RÙ>]ØZkH&<oi)ZûÀ?m<Y¹!Ñ4Ó9í´Þ6 c®![·MkÒÑá¶mDw
&IÊPaöe(®ZÄtT\òìUâÜ<Nn
<%Â@
W¨§Áá*/øQ\ðÍunîMmXG7¬ëÜo25JøþÀùæMtÀçô,Mòf|Qnfu£ø\oµ4}ÑÊ
T[Z|¬$Ñ
´4F4<àÝ¢ç¹ÚîK¦É@µ*lóB_j×$OÆxí c?IK@¸
Üú¾7Ñg\m¦6Íû=%yê)<îfzÐ\ÓѵùS.ÅÄyÆ'>îÏîH;öÞ¨]¢bvqà³eØþ,8±¯Çp»å3?Ð×fz-7ú¶ïÕô¶ÛÞöÚ¸¿¯}ÿÉEÛþY3V
g/úà`¬}
¤]½¢83/³|ÉK¦Ñùú·òS»íct_üÅ_üñÎq[¹½x¿Ó®éuõ%¹Ûþúâ²Üeû«âàÀ¡C
A$\ ÎDçÈ74Ûîv7yö%/k?~:a¦Óþë¾üå/ÿûN;I"ODò
è#
_¸P7J OHïÚN²Q¤Ü¢%ë÷`~ìeÿ17~ã
ñ|àW5Î}6Gü~qö¯ÏV7DPJ}·
Þ)¶M¡ö;&?z÷¸ÜÔ7¬vðb{buWÈB
Û
ï
ìD þJÞs
¹(IßX!íAtRD¹]Xa¦$\^7Èfue
ÜcZ½sf³º0"dĨÞ{çW"{d? Þ¯±2~D£åÔë´®Þ"ª¯èöiÔ©®K×_Fßß8'7qváíÁú% 'øYÛs/N^,ßÌUç&Ó{A<£ï
F"k½ï½ñyS0ÏDÃÔºòµR_3=yÞêVëdøMxd7oû¸ù²Ö.;ëcbÜCkeá3ÛÞ£Ì%Pç@-ò"/aÑ\UáÑØõ>·Ç]Ûk||»iýñþËËÍ5wHºªò
níÌÒ"ÂtJ ²Û¥áa¶ý ¹$ÂK)gÃg[j.¶TðÂ.5A¨¶Vñ5d1交
k&Ôê©_0u³4ot¾z&Ùàã5ç\kíBZ"ï}Ô
Xr¨ókç Å&ïØP«ÈóZì_0¨Rðc!§-÷ÞA7-_M¶Tù[Ö1jµ$Fßä#óBjä¥J{»Ó¡r`ª\T¾¾ö¼ÑB\rZdË.÷Í ¦il
fNFµAæÁàêÙ{p`Σj®v¾c5\¯tßgaÚL|%1èhÂ
>8÷íøvmÿñ¿9çÇQ¿Qó¿ëO¿kcï?®ê\àgwk}aÀÿÞ0ª^ØS¯>a0_ß/xÞQJ«Þ`#¥ÔcËYêw¬¥÷Ê}ð¹OÎ_ª©9D¿+Ek(32ðª®ÒGg$®µ;bà·ËXêZi3
a¨»j»m
±¥E
¾¬@覆}l)¥
ôLWªì^Ø]`>ðî¶OlO5æDa6i4kÛ}7£tÛuö8:dÔRB~uèJb<OgÌI
Æaa°wí%Ä£8âì£VR$å#
*ÎNVFž¨£K
ä'sMÖ©>nLbsÚà¯ÖzàtRKÏS'ÝWÆ»dÌQ]¼4/õj@)½ïYªW?nW÷F*óv&XÁÀúÂ#+&bb¸h[RßxpÇVÃ=>ÕÚ@]éá$æEhyzXxMã´¸ÆãùmóµápMïÇôpü¶ÜïÃöNøãùøþIx=É$
âI·mH2»u0Ô@P7 at MÞµïìç\zHüú%<Ý>Æôÿðg¬õ'üD_ð1âëú×ñD*
JV~>QZ&ݯh^ûú±k`úejO9Û"kízfCØÖ-o1FG]ÑK~sw¬oÚÐþbSÁbxÝuÿSZðÕ]¹îxì8®×¨û*ò_ ÿ
H,ÓÙ;c¼k¯WonzõØlñùÌ3Û×5üÇ¿×âZ¿á*믾k½ò;Vª:ùp*%<ë
×nX÷ê¥n>+ü{`{Ú?8q¶JË>°@OÀSðáB=ø®m*ÝqÝwsò)Q׿0¨¥cìêú¦ö-ÅsþPCßvÕç9¶7µÚSË1kÍz͹zWÂ1$
Q[=qµ1&èFMùÞÅ
YðÂØï¬Özn(Üaü8&J)[íD-P"?qä`ÚÁ7§vÅ$8çRfþÄ<Ø6Î,û^µí4®m À&°fáo¢]`ÚL&EQ;ÞÞ¢-£snBèÓ:§'Æyìys¶Ë8M1ãcµó
wÌTìO¼IÙpÖitÁÌnØçqt)Àq"q)Ë´8Ôáêhd)<Ä1§¼®ã¸¥dîi=1Ú,®³µ¹<Jx ë}}LO| l×½Ô1cû´Õ8cK8¦TÕ1}Ø÷¡V}
_úããµömßÛúyC
OE¹ÕëÅ$øÛÍ6Üé÷kïgøé|RcÍxº
W Ü
½¨[ìfÈõ\¼\%í\ËÞ®f_ñè[D+nvàúH®ùl©uMɶ²y£¿Ôz¨+WÛ; ð8¼ÓX¨ôUµÕ*ѳ±¼wÑT1»qvâáÔÎN®)%©¼GjvÄ4FOnÈbñ¶Y¬-¦rìËMö~V3«õÛ_qf9|SÍzƧU Ó>z£È
oúaEÆcåh5ØÕnæ»ûÍÝïÅþùßá+Îå¿ÃZ&½Çú
ÿp."âaQ8
ÖÇ1üçó#çòïçhkéw&²Ü¹wüðP|øRnqôÉ´®F2£9×ܽýÊÎHc´Óço&n¤Þi4õî
ol5qhÍùmm¢]µd^©¿rvHZxgâ÷¢ZpU-Ýxu£Ú'×ta<Dd¹FÚ`Ú©ûpv5iÙPE0·Ý¶V£!Â÷²ûy«*ÔZ=úÒ9wÎ[KTÝꦼòúïl[Í,¦qÜ6¥GÝvßÃÔÐ\k-;Û¦?;.ÊÔ£ÆâmOþ\k#ÛêXÇY}ÆBV25÷àYWF4
8nU !ä®Ì5*mãRÐRß
#Þ6¨Ð¥ÎË{[¶øôBiifÜì+Ó»©øÜ_j;ÉOצqG"g4ÞðÁik|DÏ·ºØmòÜ-EaØf!Ô4nËR1üxÞ±¶)eÆHË´¤8Cv?ÇÃ~ÜÉ°FaNÓ\Ja>&ÇÀ¥ý(ó &qÈöS6P»Vr/³:çV×·}Þ×Æ.uÔw5w^OGjý*B;mÿzd~¿¨>Çð¨àõuýÔu
ÚµÖs
_×áó fÍ'²jxâ))º÷Úp¥0åcTèl]ë=EkY^¸4V,´VkÔÎ òÀXL`:ÆÔëì7Ë2ܸÐÊNÇR³Ão§/<ݧ.Fï&Ã7zá='tG!{`Sà
)òPo+ÕñX;Ã}+jÙz
f
RàÌTÉOYH3°Z2N8À¯×:åF²d{ÀÛj&q\§_ºtݦón¶
ÌMøu
OmiÄlxžUVÅ&óÀOM¤hoËg!áï¦ÌèX¥Ñ5µÚNLÅxYY+æ¹Î˶sµà¬:NÙ°u#>ÌË»½¹a\1!L<s«v8£úÙe:Aù=ͳÑrÝy^7Ê}.G#ÌÌâmR.C5ÚÌ,æ0¶f*«O¡©dBÊe cÜÈÝwýO!(Ñ1¦ã¬S9\{à~ϼÛ
/z¨Å×£©º¥éù/_ql Qú^Ä=´Oº,ðoº¿Æÿá/1"ßô
]Â
nSæ´*#²»Ñ¸Å>-1%h®wËÛt
ÒÖ«
/w
Ø:pQ®y9Ø¥r
lºæ¿&åh0ZÚê ¶±¢¥&
ݧªBVÛzÆÝvÿ3NEÖu÷1îÌîNªÚ}ógQ[1\'®{ܶóÜs´%½;FÞcï¶ÐIVëè/¸¬ïÎAZy'èvzÍ´ºëOÁYS'á
kd×p®K;fÌìýø£_eºæî:¸\sÚ$zÞEö^ù9h
ÀWaLCõEZQV¼m>jéÁÇ
³ß¼?;Vkywî0Ü*díAZä¸ð5ßÎÑÓ:Ó_Ç»¥»ýó0µ~oᲡqÖyÖ>×ðñx\cýß'4Äô@=
¬îÌ
08ç¬wñ½Áÿ³sÉCBøíëþøçêß{N߸ùWNÿZÚ;òKÝNÛ®ÒQýS]ûC1.¿¸ë«c]T=v¶]qÒ ðvÃ)¨]1#î·\NÆݨÚûàTSïh ¶|ô6´Û¥^)w µ«~°CÛL¬×Vh£f¬&OÙ¬«~_(£²0G)£á©ê²Ö
MÐIèØlµ<#ÀCÎÙzç½µV®ø<¾cIѦôpfÄ õÜ{ÊÅs:Ĭ?ÙÛâNDupËTXcë§I<°K^æ)JW¾®IÑÕ´CmR'$ÍΧ¨röärY1FiI>9ê[¿¸FÓ°eö¹
ô6Ø;C64ìlù2.ÜÉ
JÖZW*ã:Ý
&`AÔººuÊýÓ
"¦d»Tq3f`°i·<Vuê3náÄ¥Ç}"q¯vrianñVì¾aÜ.ÓµC¢jö'\X" }à)íôqöíÄRJµ§}æ`K±j6'ÍT¥Å¯>E«D-Gð
eÖ5:¿îO=
GÞ
MªÇe]=L
éPW4c"¢_ïóB"Ãô3øG.zôþ~Vl?äóJ8gU)"z^ùÖµüÂMf¥âî¡
Sv"ÍØp¢ëâèg¼0M>9¦6®cgïý´N8#õ(íÀÈ
±÷âë2/r0ãÚÌ"Rï_v¤NåðÄGÆèGµ
fÊZ§9Ù*×-ó~swj}¡N´9ÙMò¯}å0ÓÈóp5Kt0?CaA¸^];V0¥Ö1øÚt¾èpGsómm+¨Â¯SúP'm §õR\Åu!ñRÚN#éd¤®iâÁ0_Ô<T
I|Ó/ʼSånãGcM¶¶!ópu2
°
`Q¢ïè7\b1'¿Ã ÐqÇ¡°ûäZ¬bx7ò
Sfo!£õ´Ó½`¢[fæ«ÜbL»¿óáà=¡§yîþÎró©ãG÷9FöƯ,JÁÿâQ¨OX 9I%§¼óî`sÞSÊ3*+eF¦6¹;ö)Å¥¡ò
qÔfý
©÷
\u)zYb¬Ò¹ÍÙÜ\Âî/¬
*«3NÞmõPÆ
ºãC©3¿ØìÃ7îÞÙáЪV5&¼zÐÙ¦¼(Qðgì{8£´QèºL¡¨cóçv«çíE¢ÏsdQ8ó3>PG2t|òÆ5÷wj ThÓ\Æ£³Á5ÃÁ·grU±DmÛ%¹ch<Cæz¡(/ÁÀBôÙéNÁź)íà±¢|à2úQ¸ß³»V[î·áß =KÅÖqÅ¡aS¹ïc袣4ÉvùòÆdßµÈøààH>U
¢Gn\FÏ}¢rL
XØÙ
XÇ]c-pæ[WôdÒ§Öi]ÒJZÓg_ÐMJ
¶
¹FØÀ£#ËËMv²Ïòx\Æ|À
l¿ð1ïë/ܾgçëDûëÔü»y~|ÂïóüBt/9òÛ0
(c) 1996 Demon Systemsy¡×7
1.1 ogg-tools/oggmerge/tools/Makefile.am
Index: Makefile.am
===================================================================
## process this file with automake to produce Makefile.in
AUTOMAKE_OPTIONS = foreign
EXTRA_DIST = midimerge.c
1.1 ogg-tools/oggmerge/tools/midimerge.c
Index: midimerge.c
===================================================================
/* midimerge.c
**
** merge a type 1 midi files tracks into one track and output
** and type 0 file.
**
** usage:
**
** midimerge input.mid output.mid
*/
#include <stdio.h>
#include <sys/types.h>
typedef struct event_tag {
u_int64_t timestamp;
int event;
int channel;
int data1;
int data2;
char *data;
unsigned long datalen;
struct event_tag *prev;
struct event_tag *next;
} event_t;
#define HEADER_LEN 14
typedef struct {
char chunkname[4];
unsigned long chunklen;
unsigned short format;
unsigned short tracks;
unsigned short timebase;
} header_t;
int is_big_endian(void)
{
unsigned short pattern = 0xbabe;
unsigned char *bytewise = (unsigned char *)&pattern;
if (bytewise[0] == 0xba) return 1;
return 0;
}
unsigned short swap_short(unsigned short data)
{
unsigned short ret;
unsigned char *dataptr = (unsigned char *)&data;
unsigned char *retptr = (unsigned char *)&ret;
retptr[0] = dataptr[1];
retptr[1] = dataptr[0];
return ret;
}
unsigned long swap_long(unsigned long data)
{
unsigned long ret;
unsigned char *dataptr = (unsigned char *)&data;
unsigned char *retptr = (unsigned char *)&ret;
retptr[0] = dataptr[3];
retptr[1] = dataptr[2];
retptr[2] = dataptr[1];
retptr[3] = dataptr[0];
return ret;
}
FILE *open_midifile(char *name, header_t *header)
{
FILE *fp;
int read;
fp = fopen(name, "r");
if (!fp) return NULL;
read = fread(header, 1, HEADER_LEN, fp);
if (read != HEADER_LEN) {
fclose(fp);
return NULL;
}
if (!is_big_endian()) {
header->chunklen = swap_long(header->chunklen);
header->format = swap_short(header->format);
header->tracks = swap_short(header->tracks);
header->timebase = swap_short(header->timebase);
}
return fp;
}
unsigned long get_var_value(FILE *fp)
{
unsigned long value = 0;
unsigned char temp = 0;
temp = fgetc(fp) & 0xFF;
value |= (temp & 0x7F);
if ((temp & 0x80) == 0x80) {
value <<= 7;
} else {
return value;
}
temp = fgetc(fp) & 0xFF;
value |= (temp & 0x7F);
if ((temp & 0x80) == 0x80) {
value <<= 7;
} else {
return value;
}
temp = fgetc(fp) & 0xFF;
value |= (temp & 0x7F);
if ((temp & 0x80) == 0x80) {
value <<= 7;
} else {
return value;
}
temp = fgetc(fp) & 0x7F;
value |= temp;
return value;
}
unsigned long make_var_value(unsigned long orig, int *len)
{
unsigned long value;
unsigned char c1 = 0;
unsigned char c2 = 0;
unsigned char c3 = 0;
unsigned char c4 = 0;
// split into 4 7bit chunks (first 3 have contine bit set)
c1 = ((orig & 0x0FE00000) >> 21) | 0x80;
c2 = ((orig & 0x001FC000) >> 14) | 0x80;
c3 = ((orig & 0x00003F80) >> 7) | 0x80;
c4 = (orig & 0x0000007F);
printf("%02x %02x %02x %02x\n", c1, c2, c3, c4);
// make the var value
if (c1 & 0x7F) {
value = (c1 << 24) | (c2 << 16) | (c3 << 8) | c4;
*len = 4;
printf("value = %d\tlen = %d\n", value, *len);
} else if (c2 & 0x7F) {
value = (c2 << 24) | (c3 << 16) | (c4 << 8);
*len = 3;
printf("value = %d\tlen = %d\n", value, *len);
} else if (c3 & 0x7F) {
value = (c3 << 24) | (c4 << 16);
*len = 2;
printf("value = %d\tlen = %d\n", value, *len);
} else {
value = (c4 << 24);
*len = 1;
printf("value = %d\tlen = %d\n", value, *len);
}
return value;
}
void write_var_value(FILE *fp, unsigned long value, int len)
{
char c;
printf("Writing %08x/%d\n", value, len);
c = (value >> 24) & 0xFF;
fwrite(&c, 1, 1, fp);
if (len == 1) return;
c = (value >> 16) & 0xFF;
fwrite(&c, 1, 1, fp);
if (len == 2) return;
c = (value >> 8) & 0xFF;
fwrite(&c, 1, 1, fp);
if (len == 3) return;
c = value & 0xFF;
fwrite(&c, 1, 1, fp);
}
void write_midi_file(FILE *fp, event_t *list)
{
char headchunk[4] = "MThd";
char trackchunk[4] = "MTrk";
unsigned long headlen = 6;
unsigned short format = 0;
unsigned short tracks = 1;
unsigned short timebase = 480; // HACK!!!
unsigned long tracklen = 0xa0b0c0d0;
event_t *event = NULL;
unsigned long varstamp = 0;
int var_len = 0;
unsigned long realtime = 0;
unsigned long metalen = 0;
int metalen_len = 0;
char trash;
// write header chunk
fwrite(headchunk, 1, 4, fp);
if (!is_big_endian()) headlen = swap_long(headlen);
fwrite(&headlen, 4, 1, fp);
if (!is_big_endian()) format = swap_short(format);
fwrite(&format, 2, 1, fp);
if (!is_big_endian()) tracks = swap_short(tracks);
fwrite(&tracks, 2, 1, fp);
if (!is_big_endian()) timebase = swap_short(timebase);
fwrite(&timebase, 2, 1, fp);
// write track chunk
fwrite(trackchunk, 1, 4, fp);
// write fake length, which we will replace later
fwrite(&tracklen, 4, 1, fp);
// now we can start writing event data.
event = list;
while (event) {
// skip end of track events
// except for last one
if (event->event == 0xFF && event->data1 == 0x2F && event->next != NULL) {
realtime = event->timestamp;
event = event->next;
continue;
}
// write timestamp as delta
varstamp = make_var_value(event->timestamp - realtime, &var_len);
printf("writing offset %d ", event->timestamp - realtime);
printf("as %08x ", varstamp);
printf("with length %d\n", var_len);
write_var_value(fp, varstamp, var_len);
switch (event->event & 0xF0) {
case 0x80:
case 0x90:
case 0xA0:
case 0xB0:
case 0xE0:
// both data bytes
// channel is already encoded in event
fwrite(&event->event, 1, 1, fp);
fwrite(&event->data1, 1, 1, fp);
fwrite(&event->data2, 1, 1, fp);
break;
case 0xC0:
case 0xD0:
// one data byte
// channel is already encoded in event
fwrite(&event->event, 1, 1, fp);
fwrite(&event->data1, 1, 1, fp);
break;
case 0xF0:
// metaevent
switch (event->event) {
case 0xF0:
fwrite(&event->event, 1, 1, fp);
metalen = make_var_value(event->datalen, &metalen_len);
write_var_value(fp, metalen, metalen_len);
fwrite(event->data, 1, event->datalen, fp);
break;
case 0xFF:
fwrite(&event->event, 1, 1, fp);
fwrite(&event->data1, 1, 1, fp);
metalen = make_var_value(event->datalen, &metalen_len);
write_var_value(fp, metalen, metalen_len);
fwrite(event->data, 1, event->datalen, fp);
break;
default:
printf("don't know this event...%02x\n", event->event);
}
break;
default:
printf("don't know this event %02x\n", event->event);
}
realtime = event->timestamp;
event = event->next;
}
}
int main(int argc, char **argv)
{
FILE *fp;
header_t header;
event_t *event_list = NULL;
event_t *temp;
int i;
unsigned long len;
fp = open_midifile(argv[1], &header);
if (!fp) {
printf("ERROR: Couldn't open file, or invalid file..\n");
return -1;
}
printf("chunkname = %c%c%c%c\n", header.chunkname[0], header.chunkname[1], header.chunkname[2], header.chunkname[3]);
printf("chunklength = %d\n", header.chunklen);
printf("format = %d\n", header.format);
printf("tracks = %d\n", header.tracks);
printf("timebase = %d\n", header.timebase);
printf("\n");
while (!feof(fp)) {
char chunkname[4];
unsigned long chunklen;
int read;
u_int64_t current = 0;
unsigned char status = 0;
read = fread(chunkname, 1, 4, fp);
if (read != 4) break;
read = fread(&chunklen, 1, 4, fp);
if (read != 4) break;
if (!is_big_endian()) chunklen = swap_long(chunklen);
printf("chunkname = %c%c%c%c\n", chunkname[0], chunkname[1], chunkname[2], chunkname[3]);
printf("chunklen = %d\n", chunklen);
printf("\n");
chunklen += ftell(fp);
while (ftell(fp) < chunklen) {
unsigned char data;
unsigned char data1;
unsigned char data2;
unsigned long metalen;
event_t *event;
event = (event_t *)malloc(sizeof(event_t));
event->prev = NULL;
event->next = NULL;
printf("EVENT\n-----\n");
// read the timestamp
current += get_var_value(fp);
printf("timestamp = %ld\n", current);
event->timestamp = current;
// read or assume status
data = fgetc(fp);
if ((data & 0x80) == 0x80) {
status = data;
} else {
ungetc(data, fp);
}
printf("status = %d\n", status);
event->event = status;
switch (status & 0xF0) {
case 0x80:
// note off
printf("message = note off\n");
data1 = fgetc(fp);
data2 = fgetc(fp);
printf("channel = %d\n", status & 0x0F);
printf("key = %d\n", data1);
printf("velocity = %d\n", data2);
event->channel = status & 0x0F;
event->data1 = data1;
event->data2 = data2;
break;
case 0x90:
// note on
printf("message = note on\n");
data1 = fgetc(fp);
data2 = fgetc(fp);
printf("channel = %d\n", status & 0x0F);
printf("key = %d\n", data1);
printf("velocity = %d\n", data2);
event->channel = status & 0x0F;
event->data1 = data1;
event->data2 = data2;
break;
case 0xA0:
// aftertouch
printf("message = aftertouch\n");
data1 = fgetc(fp);
data2 = fgetc(fp);
printf("channel = %d\n", status & 0x0F);
printf("key = %d\n", data1);
printf("pressure = %d\n", data2);
event->channel = status & 0x0F;
event->data1 = data1;
event->data2 = data2;
break;
case 0xB0:
// controller change
printf("message = controller change\n");
data1 = fgetc(fp);
data2 = fgetc(fp);
printf("channel = %d\n", status & 0x0F);
printf("controller = %d\n", data1);
printf("value = %d\n", data2);
event->channel = status & 0x0F;
event->data1 = data1;
event->data2 = data2;
break;
case 0xC0:
// program change
printf("message = program change\n");
data1 = fgetc(fp);
printf("channel = %d\n", status & 0x0F);
printf("program = %d\n", data1);
event->channel = status & 0x0F;
event->data1 = data1;
break;
case 0xD0:
// channel pressure
printf("message = channel pressure\n");
data1 = fgetc(fp);
printf("channel = %d\n", status & 0x0F);
printf("pressure = %d\n", data1);
event->channel = status & 0x0F;
event->data1 = data1;
break;
case 0xE0:
// pitch bend
printf("message = pitch bend\n");
data1 = fgetc(fp);
data2 = fgetc(fp);
printf("channel = %d\n", status & 0x0F);
printf("bend = %02x%02x\n", data2, data1);
event->channel = status & 0x0F;
event->data1 = data1;
event->data2 = data2;
break;
case 0xF0:
// system messages
switch (status) {
case 0xF0:
printf("message = sysex\n");
metalen = get_var_value(fp);
printf("length = %d\n", metalen);
event->datalen = metalen;
event->data = (char *)malloc(metalen);
fread(event->data, 1, metalen, fp);
break;
case 0xFF:
printf("message = meta event\n");
data = fgetc(fp);
printf("type = %02x\n", data);
metalen = get_var_value(fp);
printf("length = %d\n", metalen);
event->datalen = metalen;
event->data1 = data;
event->data = (char *)malloc(metalen);
fread(event->data, 1, metalen, fp);
break;
default:
printf("status = %02x\nnot implemented yet.. probably sysex\n", status);
}
break;
default:
printf("something is wrong.. got a bad status\n");
return -1;
}
printf("=====\n");
// add event to list
if (event_list == NULL) {
event_list = event;
} else {
temp = event_list;
while (temp->next != NULL && temp->timestamp < event->timestamp)
temp = temp->next;
event->next = temp->next;
temp->next = event;
event->prev = temp;
}
}
}
fclose(fp);
i = 0;
temp = event_list;
while (temp != NULL) {
i++;
temp = temp->next;
}
printf("%d events..\n", i);
// got all the events now, just write out the new file
// and remember to keep status expanded and to
// convert to deltas instead of absolute stamps
fp = fopen(argv[2], "w");
if (!fp) {
printf("Can't open output file.\n");
return -1;
}
write_midi_file(fp, event_list);
len = ftell(fp);
len -= 22;
printf("length of file = %ld/%08x\n", len, len);
if (!is_big_endian()) len = swap_long(len);
printf("length of file = %08x\n", len);
fseek(fp, 18, SEEK_SET);
fwrite(&len, 4, 1, fp);
fclose(fp);
return 0;
}
--- >8 ----
List archives: http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body. No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.
More information about the commits
mailing list