[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çÜÇÞ™'6MJk•Z‚¾‰Å:€
fù8i­SƏ®½¬`ì*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Ä1–2‘d““¤Îý
9gðœíyfG’’¹è™–âm©Õz\4€”@ 
xKõØW¼-=|8{`9æì]õMÑ{¥¼w˜\HŒm-š:Õu1Æ®3ƨˆn6–2`Ó]š_³1]TÑb‚–l«Rsgfx¹pŒ%4·<«ÚÐF
Ÿ~)­7ˆò¹·ÐèÝdÛ*‚JlDK…pï€flÊCƒý@'¶òÒ¶f}éi)5((”¶l,tÒ‹+#%Á\c:­ȹZݲ”q„uØÁ%°Ž¹ç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`
ÛžJr^áážC£mÛ³‡T­ƒ»u]—˜c€{q˜£…¸çÂ"˜wncàèGÖâ8xå\auï’Õã¿öÌ~)‚ÒÀì=t¯ÖyÆW–Ä”â fìÉ.»º¨.ËŽ¸¨>¸òa$Ä$f„¥SÇ”XlÄ8¢ÖzN
§½‡çze…0cWù0er3¸Æw¯œ1ωÁ=õ¤s—Lí뼩ízvó,fíwyã‘Ӎ½Öóà	qæ#
©yŸ})ˆ\å†õ·zj’Ñ{l˜Z×¢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/úà`¬}
¤]½¢8ƒ3/³|ÉK¦Ñùú·òS»íct_üÅ_üñÎq[¹½x¿Ó®éuõ%¹Ûþ­úâ²Üeû«âŽàÀ¡C
A$\ƒ ÎDçÈ74Ûîv7yö%/‹k?~:a¦Óþëš¾üå/ÿ–ûN;I"ODòƒ‰
è€#‡… _¸P7J OH™ïÚN²Q¤Ü¢ƒ%ë›÷`~ìeÿ1–7~ã…ñ|àW5Îœ}6Gü~qöŽ€¯ÏV„7DPJ}‹·
‹Þ)¶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øMxd—7oû¸™ù²Ö.;ë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íB˜Z"ï}Ô
Xr¨žó•kç ŸÅ&ï—ØP«ÈóZ‡Œì‰_0¨RðŽc!§-÷‡ÞA7-_M¶Tù[Ö1jµ‹$Fßä#óBj䥕ŽJ{»Ó¡–r`‡ª\T¾¾ö¼ÑB\rZdË.÷Í ž¦iŠl
fNFˆµAæÁàêÙ{p`ΣŠj®v¾c5Œ\¯“tßgažÚL|%­1èh’Â€†
>8÷íøvmÿñ¿‹9çÇQ¿Qó¿ëœOƒ¿‹k­cƒï?®ê\àgwk}aÀÿÞ0ª^ØS¯‹>a0_ß/xÞQJ«Þ`#¥ÔcËYêw¬¥÷Ê’}ð¹OÎ_ª©9D¿+Eœk™(32ðª®ÒGg‰$®µ–;bà·Ë‚˜XêZi3€…a¨»j»m
±¥E
¾¬@覆}l)¥…ôŒLWªì–^Ø•‡]`>ðî¶OlO5æDa6i”4kÛ}7£tÛuö8:dÔRBˆ~†uèJb<OgÌI…ÆaaŒ°wí–%Ä£8Œâì‚£V–R$å#œŽ…	*ΔNVFž¨£K‰
ä'sMÖ©>nLbs‚Úà¯ÖzàtRKÏSœ'Ý›W˜Æ»dÌŠQ]¼4/õj@)½ïYªW?nW÷F*óv&XÁÀúÂ#+&bb¸hŒ[Rßxp‚ÇVÃ=>ÕÚ@]éá$æEhy–zXžxMã´¸Æã€ùmóµápMïÇôpü¶ÜïÃöNøãùøþI—„x=É›$
⍉I·ƒmˆ€H2»u0Ô@Pƒ7 at MœÞµïìç\zHüú%<Ý>Æô‡ÿðg¬õ'üD_ð1âë„ú×ñD*
JV~>QZ&Ý”¯h^’ûú±k`ú‘ejO9Û"kí‹zfCØÖ-o1FG]ÑšK~sw¬oÚÐþ„bSÁbx‹݉uÿ€SZðƒÕ]¹îxì8®×¨û*ò_	ÿ›
H,ÓÙ;c¼k¯WoŸnzõØ•lñùÌ3Û×5üÇ¿×âZ¿á*믾k½ò;VŠª:ùp“*%<ë
×nX‘÷ê¥n>+Ÿü{`‘{Ú?8q—¶J­Ë‰>°@OÀ­SðáB=ø®m*ÝqÝw‰sò)Q׿0‰œ¨¥œ™cìêú¦ö-Å™sþPCßšvÕ‰ç9¶7µ”ÚSË1kÍzÍ”¹z††WÂ1Ÿ$…Q[=q‹ˆ˜µ1&èFMùÞÅ
†YðÂ؍”¬Özn(Üaü8&J)‰[íD-P"?qä`ÚÁ7§vÅ$8çR‚fŠþÄ<Ø6Ι,û^µí4®m	À&„°fáo˜¢]`ÚL&”‡EQ;ÞÞ¢-£snBèÓ:§'Æyìys¶Ë8M“1ãcµó
“‡wÌTìœO¼IÙpšÖitÁŒÌœnØçqt‹)‹À‹q„–"q)Ë´8ÔŽáêhd)<Ä1§¼®ã¸”¥dîi=1Ú,®³µ¹<Jx ë}}LO| ›l×½–Ô1cû´Õ8cKš8¦TÕ1‚}Ø÷¡V}
_úããµömßÛúyC
—OE¹ÕëÅ$øÛÍ6Üé÷kïgøé|RˆcÍxº
W Ü
½’’¨[ìŒfÈõ›\¼\%í\›ËÞ®fŸ_ñè[D+nvàúH®ùlƒÂ©uMɶ²y£¿Ôz¨+WÛÍœ¾	ð—8’“¼ÓX¨ôUµÕž*ѳ±‘¼wÑ”T’1»qvâáÔÎN®)%©¼GjvÄ4FOnÈbñ¶Y™¬-‘¦rìˉMö~V3«•õÛ–_q­f›9|SÍzƧU	Ó>‘z£È…oúaEÆcåh5Ø‘Õnæ»ûÍÝï—Åþùßá+Îå¿ÃZ&½Çú
ÿp."âaQ8
ÖÇ1üçó#真˜ˆòïœç‡hkéw&²Ü¹wüðP­|øRnŒqôÉ´®F2£9×ܽýÊÎHc´”Óço&n¤Þi4õî
ol5qhŒÍùmm¢]µd^©¿rvHZx‚gâ‹÷¢ZpU-Ýxu£Ú'×ta<Dd­¹FÚ`Ú©ûpv5iÙPE0·Ý¶V£!”÷²û•y«*ÔZ=úÒ9w΍[KTÝꦼòúïl[Í,¦qÜ6¥‚GÝvߝÃÔÐ\kˆ-;Û¦?˜;.ÊÔ£ÆâmOþ\›k#ÛêXÇY}ÆBV25÷àY‘WF4
8nU	!ä®—Ì5—*mãRƒÐRß
#Þ6¨ˆÐ¥Î‚Ë{[¶øôBiifÜì+Ó»©øŠÜ_j›;ÉO×€œ‹¦q“G"g4ÞðÁik|DÏ·ºŒØŒmòÜ-EaØf!Ô4nËR1üxލ±¶)eÆHË´¤8Cv?ÇÃ~ÜÉ°F‰aNÓ\Jaˆ>&ÇŸÀ¥ý(ó‘	&qÈöS6P»Vr/³:çV×·}Þ×Æ.uÔwœ5w^OGjý*B;mÿzd~¿¨>Çð¨àõ‘uýÔu
ÚµÖœs
ƒ_×áó fÍ'²jxâ­))–º÷Úp¥0åcTèl]ë=EkŒY^¸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‚Å„xY—Y‡+æ¹Î˶­ˆ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¦ã¬SŽ9›\{à~‡Ï¼Û…/z¨Å×£©º¥éù/_ql	Qú^Ä=´Oƒº,ðoº¿Æÿá/1"ßô
]Â
nSæ´*#²»Ñ¸Å>-1%h‚®wË€ÛˆŒt
ÒÖ«Ž…/w…Ø:pQ®y9ŒØ¥r
lºæ¿&åh0Z’Ú­êƒ	¶±¢¥&
Ý–§ªBVÛzÆÝvÿ3NEÖu÷1îÌîNªÚ}ógŒQ[ž1\'®{ܶóÜs´%½;—FÞcï¶Ð„“IVëè/¸¬ïΓAZy'èvzÍ´ºë€OÁYS'á
kd×p®K;fÌìý•ø£_e˜ºæî:¸\sÚ$zÞEö^ù•9h…ÀWaLCõEZ‹ƒ­QV¼m>‡jéÁÇ…³ß¼?;Vkywî0Ü*d˜íA‡Zä’¸ð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”ÑÕ´CmšR'$ÍΧ¨röärYˆ1FiI>9ê[¿¸FÓ°eö•¹
ô6Ø;C64ìlù2.ÜÉ
JÖZW•*ã:Ý
&`AÔº”ºuŽÊýÓ
Š"¦d»Tq€“3f`˜°i·<Vuê3náÄ¥Ç}šŸ"q¯vrianñŠVì¾aÜ.Ó„µC¢jö'\XŽ" }à)í‘ôqöíÄRŽJµ§}æ`K±j–6'Í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®c™gïý´N8€#õ(‡íÀÈ
±÷âë2/žr0ã€ÚÌ"Rœï‹_v¤NåðÄG™ÆèGµ
ŽfÊZ§9Ù*×-ó’~swj}¡N´9ÙMò•¯}å0ÓÈóp5KŠt0?ŽCaA¸^];V0¥Ö1øÚt¾èpGsómm+¨Â¯SúP'm §õRŠ\Åu!ñ“RƒÚN#éd¤®ƒiâÁ0_Ô<‡T
I­|Ó/ʼSånãGƒcM¶¶!ópu2
°
`Q¢ïœè7\b1'¿Ã ÐqLJ¡°ûäZ¬b‘x7ò…Sfo!£õ´Ó½`ž¢[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>PG2t|òÆ5÷wˆj ThÓ\Æ“£³Á‰5ÍÁ·grUŒ±DmÛ%¹c€h<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~|ÂïóüB˜t/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