Skip to content

Commit

Permalink
Merge pull request #3 from jordanalwon/dev
Browse files Browse the repository at this point in the history
Various minor Updates
  • Loading branch information
jordanalwon authored Jun 30, 2024
2 parents c2e973f + 7f85890 commit 0e375c4
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 78 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
(c) 2024, Jordan Alwon

## Installation
*.aup3-Converter* depends on the Python packages NumPy and Soundfile.
*.aup3-Converter* has following dependencies:
- Numpy
- Soundfile
- tqdm

## Export Data
```python
Expand Down
54 changes: 33 additions & 21 deletions convert.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from reader import SQLite3Reader
from binary_stream import BinaryStream
from name_space import NameSpace
from xml_object import XMLObject
from .reader import SQLite3Reader
from .binary_stream import BinaryStream
from .name_space import NameSpace
from .xml_object import XMLObject
import numpy as np
import soundfile as sf
from tqdm import tqdm

class Converter():
def __init__(self, path):
Expand Down Expand Up @@ -31,32 +32,43 @@ def _rate(self):

return int(rate)

def _sampleformt(self, format_id):
def _sampleformat(self, format_id):
if format_id == 262159:
return '<f4'
return {'numpy':'<f4',
'soundfile': 'float32'}
else:
raise ValueError('Unknown sample format!')

def _channels(self):
return len(self.xml['project']['wavetrack'])

def labels(self):
if 'labeltrack' in self.xml['project'].keys():
return self.xml['project']['labeltrack']
else:
return None

def export_audio(self, file):
rate = self._rate()
wavetracks = []
for channel in self.xml['project']['wavetrack']:
waveblocks = []
sampleformat = self._sampleformt(channel['sampleformat'])
for waveblock in channel['waveclip']['sequence']['waveblock']:
binary_block = self.file.binary_sammpleblock(waveblock['blockid'])
waveblocks.append(np.frombuffer(binary_block, dtype=sampleformat))

wavetracks.append(np.concatenate(waveblocks))
audio = np.stack(wavetracks, axis=1)

sf.write(file, audio, rate)
channels = self._channels()
sampleformat = self._sampleformat(self.xml['project']['wavetrack'][0]['sampleformat'])
blocks = len(self.xml['project']['wavetrack'][0]['waveclip']['sequence']['waveblock'])
with sf.SoundFile(file, mode='w', samplerate=rate, channels=channels) as soundfile, tqdm(total=blocks*channels, desc="export audio") as pbar:
for idx in range(blocks):
c_data = []
for c in range(channels):
block_id = self.xml['project']['wavetrack'][c]['waveclip']['sequence']['waveblock'][idx]['blockid']
binary_block = self.file.binary_sammpleblock(block_id)
c_data.append(np.frombuffer(binary_block, dtype=sampleformat['numpy']))
pbar.update()
o_data = np.stack(c_data, axis=1)
soundfile.buffer_write(o_data, dtype=sampleformat['soundfile'])
return

def export_label(self, file):
def export_label(self, file, sign_digits=6):
with open(file, 'w') as f:
for label in self.xml['project']['labeltrack']['label']:
f.write(f"{label['t']:.8f}\t{label['t1']:.8f}\t{label['title']}\n")
for label in self.labels['label']:
f.write(f"{label['t']:.{sign_digits}f}\t{label['t1']:.{sign_digits}f}\t{label['title']}\n")
return

if __name__ == "__main__":
Expand Down
11 changes: 7 additions & 4 deletions name_space.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ def __init__(self, binary_stream):
self.binary_stream = binary_stream
self.name_space = {}

# Skip unkown start sequence
self.binary_stream(2)
# Skip start element
self.binary_stream(1)

self.string_block_size = self._indecator()
self.name_space['string_block_size'] = self.string_block_size

while bool(self.binary_stream):
indecator = self._indecator()
Expand Down Expand Up @@ -34,6 +37,6 @@ def _block_length(self):

def _text(self, l):
s = ''
for _ in range(l//2):
s += struct.unpack('s', self.binary_stream(2)[:1])[0].decode(encoding='utf-8')
for _ in range(l//self.string_block_size):
s += struct.unpack('s', self.binary_stream(self.string_block_size)[:1])[0].decode(encoding='utf-8')
return s
104 changes: 52 additions & 52 deletions xml_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,61 +4,61 @@ class XMLObject():
def __init__(self, binary_stream, object_names):
self.binary_stream = binary_stream
self.object_names = object_names
self.string_block_size = self.object_names['string_block_size']

while bool(self.binary_stream):
indecator = self._indecator()

match indecator:
case 1:
obj_name = self._object_name()
if hasattr(self, obj_name):
if type(getattr(self, obj_name)) == list:
getattr(self,obj_name).append(XMLObject(self.binary_stream, self.object_names))
else:
setattr(self, obj_name, [getattr(self,obj_name),XMLObject(self.binary_stream, self.object_names)])
if indecator == 1:
obj_name = self._object_name()
if hasattr(self, obj_name):
if type(getattr(self, obj_name)) == list:
getattr(self,obj_name).append(XMLObject(self.binary_stream, self.object_names))
else:
setattr(self, obj_name, XMLObject(self.binary_stream, self.object_names))
case 2:
self.binary_stream(2)
break
case 3:
obj_name = self._object_name()
text = self._text(self._block_length())
setattr(self, obj_name, text)
case 4:
obj_name = self._object_name()
value = self._integer()
setattr(self, obj_name, value)
case 5:
obj_name = self._object_name()
boolean = self._bool()
setattr(self, obj_name, boolean)
case 6:
obj_name = self._object_name()
value = self._integer()
setattr(self,obj_name, value)
case 7:
obj_name = self._object_name()
long = self._long_long()
setattr(self, obj_name, long)
case 8:
obj_name = self._object_name()
value = self._integer()
setattr(self, obj_name, value)
case 10:
obj_name = self._object_name()
value = self._double()
setattr(self, obj_name, value)
self.binary_stream(4) # Skip unknown sequence (FFFF) TODO
case 12:
obj_name = "head"
text = self._text(self._block_length())
if hasattr(self,obj_name):
self.head += text
else:
setattr(self,obj_name, text)
case _:
raise ValueError("Unknown Indecator!")
setattr(self, obj_name, [getattr(self,obj_name),XMLObject(self.binary_stream, self.object_names)])
else:
setattr(self, obj_name, XMLObject(self.binary_stream, self.object_names))
elif indecator == 2:
self.binary_stream(2)
break
elif indecator == 3:
obj_name = self._object_name()
text = self._text(self._block_length())
setattr(self, obj_name, text)
elif indecator == 4:
obj_name = self._object_name()
value = self._integer()
setattr(self, obj_name, value)
elif indecator == 5:
obj_name = self._object_name()
boolean = self._bool()
setattr(self, obj_name, boolean)
elif indecator == 6:
obj_name = self._object_name()
value = self._integer()
setattr(self,obj_name, value)
elif indecator == 7:
obj_name = self._object_name()
long = self._long_long()
setattr(self, obj_name, long)
elif indecator == 8:
obj_name = self._object_name()
value = self._integer()
setattr(self, obj_name, value)
elif indecator == 10:
obj_name = self._object_name()
value = self._double()
setattr(self, obj_name, value)
self.binary_stream(4) # Skip unknown sequence (FFFF) TODO
elif indecator == 12:
obj_name = "head"
text = self._text(self._block_length())
if hasattr(self,obj_name):
self.head += text
else:
setattr(self,obj_name, text)
else:
raise ValueError("Unknown Indecator!")

def _indecator(self):
return struct.unpack('B', self.binary_stream(1))[0]
Expand All @@ -72,8 +72,8 @@ def _block_length(self):
return self._integer()
def _text(self, l):
s = ''
for _ in range(l//2):
s += struct.unpack('s', self.binary_stream(2)[:1])[0].decode(encoding='iso-8859-1')
for _ in range(l//self.string_block_size):
s += struct.unpack('s', self.binary_stream(self.string_block_size)[:1])[0].decode(encoding='iso-8859-1')

return s

Expand Down

0 comments on commit 0e375c4

Please sign in to comment.