From 1abb71f1010f142d2d8e1895c69fa0a8f8b604c3 Mon Sep 17 00:00:00 2001 From: Haroldo de Oliveira Pinheiro Date: Wed, 2 Aug 2017 19:43:35 -0300 Subject: [PATCH 1/9] Added PyDev project --- .project | 17 +++++++++++++++++ .pydevproject | 5 +++++ 2 files changed, 22 insertions(+) create mode 100644 .project create mode 100644 .pydevproject diff --git a/.project b/.project new file mode 100644 index 0000000..9299c89 --- /dev/null +++ b/.project @@ -0,0 +1,17 @@ + + + vgmparse + + + + + + org.python.pydev.PyDevBuilder + + + + + + org.python.pydev.pythonNature + + diff --git a/.pydevproject b/.pydevproject new file mode 100644 index 0000000..40e9f40 --- /dev/null +++ b/.pydevproject @@ -0,0 +1,5 @@ + + +Default +python 2.7 + From 6cef3dfea72c3c154d385ec0e855616c3687748f Mon Sep 17 00:00:00 2001 From: Haroldo de Oliveira Pinheiro Date: Wed, 2 Aug 2017 20:14:54 -0300 Subject: [PATCH 2/9] Added unit test for a 1.01 VGM --- .pydevproject | 3 +++ ...Kidd in Miracle World - 01 - Title Screen.vgm | Bin 0 -> 884 bytes test/test.py | 12 ++++++++++++ vgmparse/__pycache__/__init__.cpython-36.pyc | Bin 0 -> 4208 bytes 4 files changed, 15 insertions(+) create mode 100644 test/Alex Kidd in Miracle World - 01 - Title Screen.vgm create mode 100644 test/test.py create mode 100644 vgmparse/__pycache__/__init__.cpython-36.pyc diff --git a/.pydevproject b/.pydevproject index 40e9f40..0e3729e 100644 --- a/.pydevproject +++ b/.pydevproject @@ -2,4 +2,7 @@ Default python 2.7 + +/${PROJECT_DIR_NAME} + diff --git a/test/Alex Kidd in Miracle World - 01 - Title Screen.vgm b/test/Alex Kidd in Miracle World - 01 - Title Screen.vgm new file mode 100644 index 0000000000000000000000000000000000000000..f2ff322a7283fe5021608a0990906760491eade5 GIT binary patch literal 884 zcmV-)1B?70iwFP!000023%ylKNR&|&J_d<2N+}Uh5VLe6U5TW~O{*4B9b+Y*axLT&RlnRo{#8kTzp7H)$;9_?zrp>D`#Hh0 zoZ=qd$U_|951h|)p<3dbyp1E82f2(#c^A)dFGqQjmo%qBcM7WmOhJRwd0pt-t-sVrds0C4SNs@@5ENi|6`z`E#p4GgfLAk^b z`6!$?W^)OfB;Z!TNN4lu=FQk%iRC2;d}i=mo7-cqw8-Ke)!YSy2`)AqCB`Anz`6`; z7?zhbE@{O>IEq&c`%FVbz!ZcR9f*J~rBQ5Qmeb2FvJc2pvVURM4^&hm%1J4|(I74u zTd|8$#O=(k%s+J+;hKC}(S~t!Ac%!rN9| zczRusTql#MW^S%aT*&u%yI0|uzmMpjJ4yGNA<&7qOqB%3sni9_s`USNbQK5Q7-Woi zZ$;>0AXAPZcicp!*#rC@&K5c|RC*!6~U0etgu$$~H{{%Q0RgsJ7(3L(YbMe~IclOh3Q{$lqBcC$ zQ479u2{oX`)Vw;-uERtJjZX)>4kMx#zaZuoj7KoHQ3$aXwg2{ K+`~^82mk=VqOAG= literal 0 HcmV?d00001 diff --git a/test/test.py b/test/test.py new file mode 100644 index 0000000..82829cc --- /dev/null +++ b/test/test.py @@ -0,0 +1,12 @@ +import unittest +import vgmparse + +class TestParsing(unittest.TestCase): + + def test_vgm_1_01(self): + with open('Alex Kidd in Miracle World - 01 - Title Screen.vgm', 'rb') as f: + file_data = f.read() + parser = vgmparse.Parser(file_data) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/vgmparse/__pycache__/__init__.cpython-36.pyc b/vgmparse/__pycache__/__init__.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a3ba3231ba57b40e5cdf88e580ef1e8e49edb486 GIT binary patch literal 4208 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 OQkvVav6`qFb@^Xn#;~aX literal 0 HcmV?d00001 From cafbd17a061c2c87d2fb3c6275c10b220206fba3 Mon Sep 17 00:00:00 2001 From: Haroldo de Oliveira Pinheiro Date: Wed, 2 Aug 2017 20:24:19 -0300 Subject: [PATCH 3/9] Improved unsupported VGM version error messsage --- vgmparse/__init__.py | 6 +++++- vgmparse/__pycache__/__init__.cpython-36.pyc | Bin 4208 -> 4404 bytes 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/vgmparse/__init__.py b/vgmparse/__init__.py index 7f5af13..c86d45a 100644 --- a/vgmparse/__init__.py +++ b/vgmparse/__init__.py @@ -266,4 +266,8 @@ def validate_vgm_data(self): def validate_vgm_version(self): if self.metadata['version'] not in self.supported_ver_list: - raise VersionError('VGM version is not supported') + raise VersionError('VGM version %s is not supported' % self.version_str()) + + def version_str(self): + version = self.metadata['version'] + return '%01x.%02x' % (version >> 8, version & 0xFF) diff --git a/vgmparse/__pycache__/__init__.cpython-36.pyc b/vgmparse/__pycache__/__init__.cpython-36.pyc index a3ba3231ba57b40e5cdf88e580ef1e8e49edb486..9fcee869c484cb412629842b2ca6b1ef468b7258 100644 GIT binary patch delta 397 zcmeyMutkZ>n3tDpQ(RM|y~akaB1Xn{lWQ5D@v5b$w=hKUq_74vXliWEVAAHPXJ%kv za0cRH6(CW=kj0R~C<&q&v)PLjN|;iZfNbVw1~G9t44BJm8G$ZhOkuWX0Fo>Y3~5YaAUCl>-NdPC zU|6B2YG71RBmmU)@;{K!WCXiIlc`7#$OF5*h!eyD6I>ux1d!loWKduz23g9$$i-MC w6p&a{oLZy@^&rTJn!J-e`E8X!ijfRJn8FP*1&E97CNJT)XX0R){FuKN09ABVtN;K2 delta 147 zcmdm@^g)5kn3tDpdPq~`4E2p%MU0HkCf71PV`U9y&{W%8z@*I+$i%?F;0(mYGC-n+ zA&Vh}Q4&NmX0sPblrW_*H8VCbrZ50CF#8oL0M%5uUfbC=t0a-?y$!P-ila~wh0syrKCU^h< From b3cfd23d5fc7d0829e7ac9db1a09b7a4fb48c1a8 Mon Sep 17 00:00:00 2001 From: Haroldo de Oliveira Pinheiro Date: Wed, 2 Aug 2017 20:55:06 -0300 Subject: [PATCH 4/9] Added support for VGM 1.01 --- test/test.py | 8 ++ vgmparse/__init__.py | 91 +++++++++---------- vgmparse/__pycache__/__init__.cpython-36.pyc | Bin 4404 -> 4339 bytes 3 files changed, 52 insertions(+), 47 deletions(-) diff --git a/test/test.py b/test/test.py index 82829cc..d7030bf 100644 --- a/test/test.py +++ b/test/test.py @@ -7,6 +7,14 @@ def test_vgm_1_01(self): with open('Alex Kidd in Miracle World - 01 - Title Screen.vgm', 'rb') as f: file_data = f.read() parser = vgmparse.Parser(file_data) + + # The first command is a GG Stereo command + self.assertEqual(0x4F, ord(parser.command_list[0]['command'])) + self.assertEqual(0xFF, ord(parser.command_list[0]['data'])) + + # The second command is a SN76496 Latch/Data command + self.assertEqual(0x50, ord(parser.command_list[1]['command'])) + self.assertEqual(0x80, ord(parser.command_list[1]['data'])) if __name__ == '__main__': unittest.main() \ No newline at end of file diff --git a/vgmparse/__init__.py b/vgmparse/__init__.py index c86d45a..3018686 100644 --- a/vgmparse/__init__.py +++ b/vgmparse/__init__.py @@ -18,41 +18,39 @@ class Parser: # Supported VGM versions supported_ver_list = [ + 0x00000101, 0x00000150, ] # VGM metadata offsets metadata_offsets = { - # Version 1.50 - 0x00000150: { - 'vgm_ident': {'offset': 0x00, 'size': 4, 'type_format': None}, - 'eof_offset': {'offset': 0x04, 'size': 4, 'type_format': 'ImVvL~1M+gZC#*L4d6hUTvWM?@L)9Zq3 zG#U?>NjwoR#ye#FDdK^6H1T5Mfr|$Z*7UN2;-SC#x~96izN(&2BYVT{sZ`4C!e=*o zMz`H%R?7jvd0Lep1dC8)2t|&pD3GIA;zfxPEmWA;6l5*54Rd1V#w-~#FJ`HjrDK+f zSr)C@e!@1)VY^A)ft}c8Sa%%Q6SI8GdN(sg3;VGDITRHh!2z-f9K<2AHV)$mSqG2e zF|sZm#}j0eIErIrJyi2BKEA8w+V2IG#h@Zd{KC@1p=HJZ8teQeXOp30O|!Ld%O0#D z%LDQ}bVHp2HrVO~4Lxj->_ig|M= z#;db`Vp5cGYd@yeN_04=mlAzxB|>N=pewR;{PSG%y0#MEU_q}bhNDMCa|SE6?_kdO zENri{I>(MYRK<$h^l6e-XBzG%%Y_;#FQ1rWckL(PNL)nZ2StJ$&kfBu1qol$_wfO2W6BdrciSV!@{$ zVG7FqTGGjghZ*lq(h3T6YjBw$eBqrO+KFoDAuuJ14v}S9;W5b+tu#+JcDyyleufL_ k@5~O*Wj-=5{FZqoIa5|x&W^dBwA<}@d&2GwKV;wj0a=L%)&Kwi delta 1238 zcmah{OKVd>6rMA8X6_@;Cap1T)il29LJ?dTMNm|9qqX=d25nJJTY7_!+?z!f6C+0O z0Yc@9t1b#6xYfFH=dVy)h&y*KbS-%9#N48SF6KMm{pQ>==k=9CU_uvh7)K1-kT{kSwlQJlmE024C640QJyusZj+@BZxEZ&Qb+CdHWL>P{ zR28lym;2R_IK0qBV#O6b#c|G7egFGH}+B*T&B(c{2cj_+d8 zXcC8e(Bn8#W*w{L^)+qHk_ej3rJ6O|pt)ccYrrzxtYN7EHw0&KCxY{TKW}Q>ND0&i zck9m#Qf$_ucdF=)PX$%#e^6Qbpw2+ybi9uz2pIP)1rCfy2OJ;NKgVH$b6O8+>XN=f zWi%UYQw6VW-YRgK(`~?HEsDedZa0>(518=&>$72h^=bjyIRJB!wclx zY-y?0eipMCrUg=HLTS)5m^Nq|%oxlX%o!90^9F}#rwY+yx8xS5f{A_?Ub<(Yuu42U zNU+|8bm~;sCPC6UMkib)Fa<%6bzq739B(!R?mqJ9I3;A9LHg1UWkVIiDvh0)3M?&^C|!chWKmNg6oD-U@q4FVLMEHA7*P2U0d7L8=T jKq~r?eF3@XdG4W5ibJ$FKj~$qQ*_Qb`<=1qTK>sTbD0h! From 7c7ab1dd3f48983f2ded76830a76b9696837a112 Mon Sep 17 00:00:00 2001 From: Haroldo de Oliveira Pinheiro Date: Wed, 2 Aug 2017 20:56:52 -0300 Subject: [PATCH 5/9] Updated the line about supported versions --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index af7f861..bd57936 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ A Python module for parsing [VGM (Video Game Music)](https://en.wikipedia.org/wiki/VGM_(file_format)) files. `.vgm` and `.vgz` (Gzip compressed) files are supported. -Currently, only version 1.50 of the VGM specification is supported. +Currently, only versions 1.01 and 1.50 of the VGM specification are supported. ## Installation The `vgmparse` module can be installed directly from GitHub using `pip`: From adecf3ef505ce6bfaafdf21f7d255018579feb7b Mon Sep 17 00:00:00 2001 From: Haroldo de Oliveira Pinheiro Date: Wed, 2 Aug 2017 21:19:37 -0300 Subject: [PATCH 6/9] Created test for the saving function --- test/test.py | 9 +++++++++ vgmparse/__pycache__/__init__.cpython-36.pyc | Bin 4339 -> 4339 bytes 2 files changed, 9 insertions(+) diff --git a/test/test.py b/test/test.py index d7030bf..88a5bc2 100644 --- a/test/test.py +++ b/test/test.py @@ -1,5 +1,6 @@ import unittest import vgmparse +import tempfile, time class TestParsing(unittest.TestCase): @@ -15,6 +16,14 @@ def test_vgm_1_01(self): # The second command is a SN76496 Latch/Data command self.assertEqual(0x50, ord(parser.command_list[1]['command'])) self.assertEqual(0x80, ord(parser.command_list[1]['data'])) + + def test_save(self): + with open('Alex Kidd in Miracle World - 01 - Title Screen.vgm', 'rb') as f: + file_data = f.read() + parser = vgmparse.Parser(file_data) + + with open('{0}/test-save-{1}.vgm'.format(tempfile.gettempdir(), time.time()), 'wb') as o: + parser.save(o) if __name__ == '__main__': unittest.main() \ No newline at end of file diff --git a/vgmparse/__pycache__/__init__.cpython-36.pyc b/vgmparse/__pycache__/__init__.cpython-36.pyc index b47e7de58e1966e2bc96d5338fcea244d0ecb7bb..b71eefb5d413af6b0ffafe538bff040665477faf 100644 GIT binary patch delta 15 WcmeyY_*s$7n3tDpd-_JUw*mkxZ3S2W delta 15 WcmeyY_*s$7n3tDJEM+6xTLAzlm;|%{ From dccba33ae2300009f5b18921d676c7e2e247a4da Mon Sep 17 00:00:00 2001 From: Haroldo de Oliveira Pinheiro Date: Wed, 2 Aug 2017 21:21:30 -0300 Subject: [PATCH 7/9] Ignored __pycache__ --- .gitignore | 1 + vgmparse/__pycache__/__init__.cpython-36.pyc | Bin 4339 -> 0 bytes 2 files changed, 1 insertion(+) create mode 100644 .gitignore delete mode 100644 vgmparse/__pycache__/__init__.cpython-36.pyc diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bdaedba --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/vgmparse/__pycache__ diff --git a/vgmparse/__pycache__/__init__.cpython-36.pyc b/vgmparse/__pycache__/__init__.cpython-36.pyc deleted file mode 100644 index b71eefb5d413af6b0ffafe538bff040665477faf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4339 zcma)9OK%)m6|Q^hc6D`i+3q-wV<#rl^T^Ef4462{B$*)!CX-AiARI%6WTs>&mHSq= zt6$Z=RStHmjZk`42t>q!Rm7ehJN^i;s1*{cmXKJmLr8GWsfQmK3A$C^J@--fan5(n zxpi%3#`y?XxiVjV?P1%Iy})&0Hh{aPjk|eIgIMu;Xd!^veFgm3bg1w(Jwg$ z(*`!wM6cX0W9@+^OVapKlZJ0jbf*IKvNWM?PPk)9_E>9JQ&>aWnCgHHmXz-v#D4Vf z5s2pFSOtUj!$(aVk^dM7>+nQ2fUn_x98NRw#D3zdCd9PQrGC6{`eJ3IiQkyo-Q#fVV!KzK1njCSiA{U&qQ7gzEr}Ii~_#`RtT$PJmHV_;b1hank)z#^Q=VATTyzgk0e22TMPg8w! zWOK&FiyP_E#xCoGF|3qs&BHRQ@lrwrLj1tuP1HvB?J|_H3E$5vcHEa_$30s71 z3`Pp$5JfL)8xsDS@UIQ7*0A>~Ktm{uH0lF{8wfYCRaYOP{1L*pu)(HHB_j5FJ>;(6 zRSjrQYPk<&t{o*p`JPm7W2fN_hyFk&Mii^PW}Fy%gCRr`^(IaWsU25e#esIHf_5-~ z_%sY7bq$)Fxg!^JG2EVV5cLfh^gVc@PXNF-z%xuXuM6D|IKjCbloRxXqfH5Eo z-Qu(QlD<${VGCK`q8OdayeakD+*u2sD#JpkR`RKTgFu%5zkG^DLL!xd*jefrvP5lV zX%IWhz)l{UY1Nm&vJinn{2OXq* z#)LAhK||ByAn30 z61G*F;UEgLu|)-YEKkJ{#c6ylV>G8AZ30Q-P&uVR2$#A>mDsJ;VGrs%2*_=9 z7vVkva!jGwQ|jJB3A1>kO#D?3Kz1nG_F$9o4t1stt-$Ze$eC&GDFs>FrFtToJDxgC zX-xjVgC|0_D=001sH~<7CK%VPjNBG8xGl0|kfwwTXT_*?g2s@33I?O%F*6W@e*wY~ zgDI=>eT?mTM@+PP+K-(re#j4X8dDlmwm_Cq-GDk|3}B=H2{q>TV_-V5 z4s#8^t?jOi1-zNbS$r%Vi;ty^luEO(Ej5RL(XmlEW}3n(Nhyf^ew5mZ>{6JiQ93e7 zQi8m^2PRK%O_asc>5y`%`jL0)J%B&M6XA7@G_Nn{HPE^ZS~uXCg>Z2yJmi6|P%cs% zuh^vA-+(}hIu;%zB?D>&bvYbnU__|JR3&<6bTbO*C+zNVrxZOzve1`a=_wT_C zsV+l5s)KLTF@k%l9*6a9zwXuPo>PDF;QMua>x6O0Z}99%4Lz*ywS%TR*z0fOwW~b} zz>6OMegf|$))TY~eGDb#hmS~rtc1CMeCf1jT!xN+z!NP3pnYsH54M@-oXs;kwa!w; z`V&_%Od^GWkWV^1WFXA3r0Dbx#JXiTC6{=o(I?s>F#9=tz`-3--%xcJJ9-UIon7tf zm!o=+Dk$0;4nr0D5^@>xGnp@1To_IFN&4DKs@cmfWWxqa4||G-@52NpY%@Y9)mV*< zE`HUivWbd=A@d5iz66#0V22D2#H9XhxK>NCuC@3g9tm8n4x>hu%U9O+S1(_=y07Sq z3asBm3A4Du zxJNFi(9Q~#pm2?2>ynOfCdxM#*BY{DB(KqZ7i-*`m5F%(LcW^QL*h zTsDQmx!|CvzBJfW)n_PUFiG_2AWH1qX2GBpCOilg5-80AsPUw7f4}JuWB9ZuBh!>$ cweQ5doqpxtK^8_B Date: Wed, 2 Aug 2017 21:40:56 -0300 Subject: [PATCH 8/9] Saving implemented --- vgmparse/__init__.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/vgmparse/__init__.py b/vgmparse/__init__.py index 3018686..69d1b45 100644 --- a/vgmparse/__init__.py +++ b/vgmparse/__init__.py @@ -268,3 +268,31 @@ def validate_vgm_version(self): def version_str(self): version = self.metadata['version'] return '%01x.%02x' % (version >> 8, version & 0xFF) + + def save(self, buffer): + # Pre-fill the header with zeroes + buffer.seek(0) + buffer.write(b'\0' * 0x40) + + # Iterate over the offsets and write the metadata + for value, offset_data in self.metadata_offsets.items(): + + # Seek to the data location and read the data + buffer.seek(offset_data['offset']) + + # Unpack the data if required + if offset_data['type_format'] is not None: + data = struct.pack( + offset_data['type_format'], + self.metadata[value], + ) + buffer.write(data) + else: + buffer.write(self.metadata[value]) + + # Write out the commands + for cmd in self.command_list: + buffer.write(cmd['command']) + if cmd['data']: + buffer.write(cmd['data']) + \ No newline at end of file From 29c2399543e4f01028eb170da674ff43a3e6608e Mon Sep 17 00:00:00 2001 From: Haroldo de Oliveira Pinheiro Date: Wed, 2 Aug 2017 21:45:35 -0300 Subject: [PATCH 9/9] Documented way to save file --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index bd57936..397f9a3 100644 --- a/README.md +++ b/README.md @@ -79,3 +79,12 @@ then seek and read like a file: @>>> vgm_data.data_block.read(5) b'\x82\x88\x8a\x8a\x88' ``` + +### Saving a VGM file + +You can save the VGM back into a file by using the `.save()` method: + +``` +@>>> vgm_out = open('newfile.vgm', 'wb') +@>>> vgm_data.save(vgm_out) +```