Skip to content

Commit

Permalink
Merge pull request #16 from zsinskri/r128-gain-q-formatting
Browse files Browse the repository at this point in the history
format R128 GAIN tags as Q7.8 number
  • Loading branch information
sampsyo authored Jun 20, 2019
2 parents 1940c9c + db32322 commit dab325d
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 4 deletions.
31 changes: 27 additions & 4 deletions mediafile.py
Original file line number Diff line number Diff line change
Expand Up @@ -1407,6 +1407,29 @@ def __delete__(self, mediafile):
delattr(mediafile, 'images')


class QNumberField(MediaField):
"""Access integer-represented Q number fields.
Access a fixed-point fraction as a float. The stored value is shifted by
`fraction_bits` binary digits to the left and then rounded, yielding a
simple integer.
"""
def __init__(self, fraction_bits, *args, **kwargs):
super(QNumberField, self).__init__(out_type=int, *args, **kwargs)
self.__fraction_bits = fraction_bits

def __get__(self, mediafile, owner=None):
q_num = super(QNumberField, self).__get__(mediafile, owner)
if q_num is None:
return None
return q_num / pow(2, self.__fraction_bits)

def __set__(self, mediafile, value):
q_num = round(value * pow(2, self.__fraction_bits))
q_num = int(q_num) # needed for py2.7
super(QNumberField, self).__set__(mediafile, q_num)


class ImageListField(ListMediaField):
"""Descriptor to access the list of images embedded in tags.
Expand Down Expand Up @@ -2015,7 +2038,8 @@ def update(self, dict):
)

# EBU R128 fields.
r128_track_gain = MediaField(
r128_track_gain = QNumberField(
8,
MP3DescStorageStyle(
u'R128_TRACK_GAIN'
),
Expand All @@ -2028,9 +2052,9 @@ def update(self, dict):
ASFStorageStyle(
u'R128_TRACK_GAIN'
),
out_type=int,
)
r128_album_gain = MediaField(
r128_album_gain = QNumberField(
8,
MP3DescStorageStyle(
u'R128_ALBUM_GAIN'
),
Expand All @@ -2043,7 +2067,6 @@ def update(self, dict):
ASFStorageStyle(
u'R128_ALBUM_GAIN'
),
out_type=int,
)

initial_key = MediaField(
Expand Down
17 changes: 17 additions & 0 deletions test/test_mediafile.py
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,23 @@ def test_write_dates(self):
self.assertEqual(mediafile.original_day, 30)
self.assertEqual(mediafile.original_date, datetime.date(1999, 12, 30))

def test_r128_gain_stored_as_q8_number(self):
def round_trip(x):
q_num = round(x * pow(2, 8))
return q_num / pow(2, 8)

mediafile = self._mediafile_fixture('full')

track = -1.1
self.assertNotEqual(track, round_trip(track))
mediafile.r128_track_gain = track
self.assertEqual(mediafile.r128_track_gain, round_trip(track))

album = 4.2
self.assertNotEqual(album, round_trip(album))
mediafile.r128_album_gain = album
self.assertEqual(mediafile.r128_album_gain, round_trip(album))

def test_write_packed(self):
mediafile = self._mediafile_fixture('empty')

Expand Down

0 comments on commit dab325d

Please sign in to comment.