Skip to content

Instantly share code, notes, and snippets.

@lukegb
Created August 24, 2011 21:15
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save lukegb/1169265 to your computer and use it in GitHub Desktop.
Save lukegb/1169265 to your computer and use it in GitHub Desktop.
Unpack music from VVVVVV's music file!
f = open("vvvvvvmusic.vvv", 'rb')
q = f.read()
FILE_NAMES = ['0levelcomplete.ogg','1pushingonwards.ogg','2positiveforce.ogg','3potentialforanything.ogg','4passionforexploring.ogg','5intermission.ogg','6presentingvvvvvv.ogg','7gamecomplete.ogg','8predestinedfate.ogg','9positiveforcereversed.ogg','10popularpotpourri.ogg','11pipedream.ogg','12pressurecooker.ogg','13pacedenergy.ogg','14piercingthesky.ogg']
startAt = endAt = -1
musStartAt = musEndAt = -1
currentMus = 0
while True:
oldStartAt = startAt
startAt = q.find("OggS", oldStartAt + 1)
endAt = q.find("OggS", startAt + 1) - 1
if oldStartAt >= startAt:
break
if endAt == -2:
endAt = len(q) - 1
sB = ord(q[startAt+5])
if sB == 2:
musStartAt = startAt
elif sB == 4:
musEndAt = endAt
print "Found entire Ogg between",musStartAt,musEndAt
print "Filename: ",FILE_NAMES[currentMus]
f2 = open(FILE_NAMES[currentMus], 'wb')
f2.write(q[musStartAt:musEndAt])
f2.close()
currentMus += 1
#print "Found OggS at",startAt,"-",endAt
@lahwran
Copy link

lahwran commented Aug 24, 2011

Me likey

@totalizator
Copy link

Exactly what I was looking for. Thanks!

@zorun
Copy link

zorun commented Aug 26, 2011

I'm just curious here... Since "OggS" is also a magic string for internal streams, how do you distinguish between the start of an ogg file and the start of a stream? Looks like there's another magic byte involved.

I wanted to do something similar at first, but because of this issue, I ended up using hard-coded offsets straced from VVVVVV... See my blog for details.

@lukegb
Copy link
Author

lukegb commented Aug 26, 2011 via email

@TerrorBite
Copy link

There is now a 16th ogg in the music file, so the FILE_NAMES list needs an extra entry. I went with "15unknown.ogg".

@nike4613
Copy link

nike4613 commented Jan 6, 2015

Only works with python 2x!

@nike4613
Copy link

nike4613 commented Jan 6, 2015

https://gist.github.com/nike4613/1b5fd6b7bb5cc5dc94cd
That one should work even with added files.

@josefnpat
Copy link

noice!

@BenjaminUrquhart
Copy link

BenjaminUrquhart commented Dec 31, 2018

I made a Java clone of this. Should work with Java 1.8+

Works with added files

https://gist.github.com/BenjaminUrquhart/53c5abf9599e457a291510e007e5b957

@mincrmatt12
Copy link

python3, works with arbitrary files:

import struct
import os

with open('vvvvvvmusic.vvv', 'rb') as f:
    data = f.read()

# find filenames

# (name, len)
headers = []
iptr = 0
while data[iptr] == 0x64:
    headers.append(list(struct.unpack("<48s4xI4x", data[iptr:iptr+0x3C])))
    headers[-1][0] = headers[-1][0][:headers[-1][0].index(b'\x00')]
    iptr += 0x3C

moffset = 0x1e00

if not os.path.exists("data/music"):
    os.makedirs("data/music")

for n, length in headers:
    with open(n.decode('ascii'), 'wb') as f:
        f.write(data[moffset:moffset+length])
        moffset += length

@csd-was-taken
Copy link

seeing someone from years ago solving your problem you didnt even know you had until 5 minutes ago is always the best feeling.

thanks guys

@Scrooge200FES
Copy link

This still works as of V2.3.

@ExtolsSuperSauce
Copy link

Had to fix some things, and posting so people don't have to go through this again.

f = open("vvvvvvmusic.vvv", 'rb')
q = f.read()

FILE_NAMES = ['0levelcomplete.ogg','1pushingonwards.ogg','2positiveforce.ogg','3potentialforanything.ogg','4passionforexploring.ogg','5intermission.ogg','6presentingvvvvvv.ogg','7gamecomplete.ogg','8predestinedfate.ogg','9positiveforcereversed.ogg','10popularpotpourri.ogg','11pipedream.ogg','12pressurecooker.ogg','13pacedenergy.ogg','14piercingthesky.ogg','predestinedfatefinallevel.ogg']

startAt = endAt = -1
musStartAt = musEndAt = -1
currentMus = 0
while True:
    oldStartAt = startAt
    startAt = q.find(b"OggS", oldStartAt + 1)
    endAt = q.find(b"OggS", startAt + 1) - 1
    if oldStartAt >= startAt:
        break
    if endAt == -2:
        endAt = len(q) - 1
    sB = q[startAt+5]
    if sB == 2:
        musStartAt = startAt
    elif sB == 4:
        musEndAt = endAt
        print( "Found entire Ogg between",musStartAt,musEndAt)
        print( "Filename: ",FILE_NAMES[currentMus])
        f2 = open(FILE_NAMES[currentMus], 'wb')
        f2.write(q[musStartAt:musEndAt])
        f2.close()
        currentMus += 1
    print( "Found OggS at",startAt,"-",endAt)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment