Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
MPAI-Private
MPAI-CAE
arp
ARP Library
Commits
51d4ec30
Commit
51d4ec30
authored
Apr 24, 2023
by
Matteo
Browse files
update
parent
af2200e0
Changes
14
Hide whitespace changes
Inline
Side-by-side
Makefile
View file @
51d4ec30
...
...
@@ -40,7 +40,7 @@ install:
test
:
$(POETRY)
pytest
cd
docs
&&
$(POETRY)
make doctest
#
cd docs &&
$(POETRY)
make doctest
test-coverage
:
$(POETRY)
pytest
--cov-config
.coveragerc
--cov-report
term-missing
--cov-report
html
--cov
=
mpai_cae_arp
...
...
mpai_cae_arp/audio/__init__.py
View file @
51d4ec30
from
mpai_cae_arp.audio._audio
import
AudioWave
from
mpai_cae_arp.audio._noise
import
Noise
import
mpai_cae_arp.audio
.utils
as
utils
from
mpai_cae_arp.audio
import
utils
__all__
=
[
"AudioWave"
,
"Noise"
,
"utils"
]
mpai_cae_arp/audio/_audio.py
View file @
51d4ec30
...
...
@@ -74,8 +74,7 @@ class AudioWave:
samplerate
:
int
channels
:
int
def
__init__
(
self
,
data
:
np
.
ndarray
,
bit
:
int
,
channels
:
int
,
samplerate
:
int
):
def
__init__
(
self
,
data
:
np
.
ndarray
,
bit
:
int
,
channels
:
int
,
samplerate
:
int
):
if
bit
not
in
[
8
,
16
,
24
,
32
]:
raise
ValueError
(
"bit must be 8, 16, 24 or 32"
)
if
samplerate
<
8000
or
samplerate
>
192000
:
...
...
@@ -92,8 +91,7 @@ class AudioWave:
return
iter
(
self
.
array
)
def
__getitem__
(
self
,
key
):
return
AudioWave
(
self
.
array
[
key
],
self
.
bit
,
self
.
channels
,
self
.
samplerate
)
return
AudioWave
(
self
.
array
[
key
],
self
.
bit
,
self
.
channels
,
self
.
samplerate
)
def
__eq__
(
self
,
__o
:
object
)
->
bool
:
if
isinstance
(
__o
,
AudioWave
):
...
...
@@ -149,8 +147,7 @@ class AudioWave:
return
bit
,
channels
,
samplerate
@
staticmethod
def
buffer_generator_from_file
(
filepath
:
str
,
buffer_size
:
int
=
1024
*
1024
*
8
):
def
buffer_generator_from_file
(
filepath
:
str
,
buffer_size
:
int
=
1024
*
1024
*
8
):
"""Return a generator that yields AudioWave objects from a file. The generator will read the file in chunks of `buffer_size` bytes.
Parameters
...
...
@@ -203,9 +200,7 @@ class AudioWave:
"""
data
=
np
.
array
([
int
.
from_bytes
(
raw_data
[
i
:
i
+
bit
//
8
],
byteorder
=
'little'
,
signed
=
True
)
int
.
from_bytes
(
raw_data
[
i
:
i
+
bit
//
8
],
byteorder
=
'little'
,
signed
=
True
)
for
i
in
range
(
0
,
len
(
raw_data
),
bit
//
8
)
])
data
=
np
.
reshape
(
data
,
(
-
1
,
channels
))
...
...
@@ -243,8 +238,7 @@ class AudioWave:
if
force
:
os
.
makedirs
(
path
.
dirname
(
filepath
))
else
:
raise
ValueError
(
f
"Directory
{
path
.
dirname
(
filepath
)
}
does not exist"
)
raise
ValueError
(
f
"Directory
{
path
.
dirname
(
filepath
)
}
does not exist"
)
with
wave
.
open
(
filepath
,
'wb'
)
as
fp
:
fp
.
setframerate
(
self
.
samplerate
)
...
...
@@ -253,6 +247,19 @@ class AudioWave:
fp
.
setnframes
(
self
.
number_of_frames
())
fp
.
writeframesraw
(
self
.
get_raw
())
def
set_sample_rate
(
self
,
samplerate
:
int
):
"""Set the sample rate of the audio.
.. versionadded:: 0.4.0
Parameters
----------
samplerate: int
The new sample rate.
"""
self
.
array
=
librosa
.
resample
(
self
.
array
,
self
.
samplerate
,
samplerate
)
self
.
samplerate
=
samplerate
def
get_raw
(
self
)
->
bytes
:
"""Get the raw data of the audio.
...
...
@@ -312,9 +319,7 @@ class AudioWave:
for
channel
in
range
(
self
.
channels
):
signal
=
self
.
get_channel
(
channel
).
array
signal
=
signal
/
(
2
^
(
self
.
bit
-
1
))
# normalize the signal
mfccs
=
librosa
.
feature
.
mfcc
(
y
=
signal
,
sr
=
self
.
samplerate
,
n_mfcc
=
n_mfcc
)
mfccs
=
librosa
.
feature
.
mfcc
(
y
=
signal
,
sr
=
self
.
samplerate
,
n_mfcc
=
n_mfcc
)
mean_mfccs
=
[]
for
e
in
mfccs
:
mean_mfccs
.
append
(
np
.
mean
(
e
))
...
...
mpai_cae_arp/audio/standards.py
View file @
51d4ec30
from
enum
import
Enum
class
EqualizationStandard
(
Enum
):
class
EqualizationStandard
(
str
,
Enum
):
IEC
=
"IEC"
CCIR
=
"IEC1"
NAB
=
"IEC2"
class
SpeedStandard
(
Enum
):
class
SpeedStandard
(
float
,
Enum
):
I
=
0.9375
II
=
1.875
III
=
3.75
...
...
mpai_cae_arp/files.py
View file @
51d4ec30
...
...
@@ -5,13 +5,13 @@ import yaml
from
pydantic
import
BaseModel
class
FileAction
(
Enum
):
class
FileAction
(
str
,
Enum
):
READ
=
"r"
WRITE
=
"w"
APPEND
=
"a"
class
FileType
(
Enum
):
class
FileType
(
str
,
Enum
):
YAML
=
"yaml"
JSON
=
"json"
...
...
mpai_cae_arp/io.py
View file @
51d4ec30
"""
This module contains functions to print and format text in the console. Consider it as deprecated, use instead rich library.
"""
from
enum
import
Enum
END
=
'
\033
[0m'
...
...
mpai_cae_arp/network/arp_pb2.py
View file @
51d4ec30
...
...
@@ -10,28 +10,27 @@ from google.protobuf import symbol_database as _symbol_database
_sym_db
=
_symbol_database
.
Default
()
DESCRIPTOR
=
_descriptor_pool
.
Default
().
AddSerializedFile
(
b
'
\n\t
arp.proto
\x12\x03\x61
rp
\"
+
\n\x0b
InfoRequest
\x12\x12\n\x05\x66
ield
\x18\x01
\x01
(
\t
H
\x00\x88\x01\x01\x42\x08\n\x06
_field
\"
S
\n\n
JobRequest
\x12\x13\n\x0b
working_dir
\x18\x01
\x01
(
\t\x12\x12\n\n
files_name
\x18\x02
\x01
(
\t\x12\x12\n\x05
index
\x18\x03
\x01
(
\x05
H
\x00\x88\x01\x01\x42\x08\n\x06
_index
\"
.
\n\x0b
JobResponse
\x12\x0e\n\x06
status
\x18\x01
\x01
(
\t\x12\x0f\n\x07
message
\x18\x02
\x01
(
\t\"
&
\n\x07\x43
ontact
\x12\x0c\n\x04
name
\x18\x01
\x01
(
\t\x12\r\n\x05\x65
mail
\x18\x02
\x01
(
\t\"
$
\n\x07
License
\x12\x0c\n\x04
name
\x18\x01
\x01
(
\t\x12\x0b\n\x03
url
\x18\x02
\x01
(
\t\"\x81\x01\n\x0c
InfoResponse
\x12\r\n\x05
title
\x18\x01
\x01
(
\t\x12\x13\n\x0b\x64\x65
scription
\x18\x02
\x01
(
\t\x12\x0f\n\x07
version
\x18\x03
\x01
(
\t\x12\x1d\n\x07\x63
ontact
\x18\x04
\x01
(
\x0b\x32\x0c
.arp.Contact
\x12\x1d\n\x07
license
\x18\x05
\x01
(
\x0b\x32\x0c
.arp.License2f
\n\x03\x41
IM
\x12\x30\n\x07
getInfo
\x12\x10
.arp.InfoRequest
\x1a\x11
.arp.InfoResponse
\"\x00\x12
-
\n\x04
work
\x12\x0f
.arp.JobRequest
\x1a\x10
.arp.JobResponse
\"\x00\x30\x01\x62\x06
proto3'
)
DESCRIPTOR
=
_descriptor_pool
.
Default
().
AddSerializedFile
(
b
'
\n\t
arp.proto
\x12\x03\x61
rp
\"
+
\n\x0b
InfoRequest
\x12\x12\n\x05\x66
ield
\x18\x01
\x01
(
\t
H
\x00\x88\x01\x01\x42\x08\n\x06
_field
\"
S
\n\n
JobRequest
\x12\x13\n\x0b
working_dir
\x18\x01
\x01
(
\t\x12\x12\n\n
files_name
\x18\x02
\x01
(
\t\x12\x12\n\x05
index
\x18\x03
\x01
(
\x05
H
\x00\x88\x01\x01\x42\x08\n\x06
_index
\"
.
\n\x0b
JobResponse
\x12\x0e\n\x06
status
\x18\x01
\x01
(
\t\x12\x0f\n\x07
message
\x18\x02
\x01
(
\t\"
&
\n\x07\x43
ontact
\x12\x0c\n\x04
name
\x18\x01
\x01
(
\t\x12\r\n\x05\x65
mail
\x18\x02
\x01
(
\t\"
$
\n\x07
License
\x12\x0c\n\x04
name
\x18\x01
\x01
(
\t\x12\x0b\n\x03
url
\x18\x02
\x01
(
\t\"\x81\x01\n\x0c
InfoResponse
\x12\r\n\x05
title
\x18\x01
\x01
(
\t\x12\x13\n\x0b\x64\x65
scription
\x18\x02
\x01
(
\t\x12\x0f\n\x07
version
\x18\x03
\x01
(
\t\x12\x1d\n\x07\x63
ontact
\x18\x04
\x01
(
\x0b\x32\x0c
.arp.Contact
\x12\x1d\n\x07
license
\x18\x05
\x01
(
\x0b\x32\x0c
.arp.License2f
\n\x03\x41
IM
\x12\x30\n\x07
getInfo
\x12\x10
.arp.InfoRequest
\x1a\x11
.arp.InfoResponse
\"\x00\x12
-
\n\x04
work
\x12\x0f
.arp.JobRequest
\x1a\x10
.arp.JobResponse
\"\x00\x30\x01\x62\x06
proto3'
)
_builder
.
BuildMessageAndEnumDescriptors
(
DESCRIPTOR
,
globals
())
_builder
.
BuildTopDescriptorsAndMessages
(
DESCRIPTOR
,
'arp_pb2'
,
globals
())
if
_descriptor
.
_USE_C_DESCRIPTORS
==
False
:
DESCRIPTOR
.
_options
=
None
_INFOREQUEST
.
_serialized_start
=
18
_INFOREQUEST
.
_serialized_end
=
61
_JOBREQUEST
.
_serialized_start
=
63
_JOBREQUEST
.
_serialized_end
=
146
_JOBRESPONSE
.
_serialized_start
=
148
_JOBRESPONSE
.
_serialized_end
=
194
_CONTACT
.
_serialized_start
=
196
_CONTACT
.
_serialized_end
=
234
_LICENSE
.
_serialized_start
=
236
_LICENSE
.
_serialized_end
=
272
_INFORESPONSE
.
_serialized_start
=
275
_INFORESPONSE
.
_serialized_end
=
404
_AIM
.
_serialized_start
=
406
_AIM
.
_serialized_end
=
508
DESCRIPTOR
.
_options
=
None
_INFOREQUEST
.
_serialized_start
=
18
_INFOREQUEST
.
_serialized_end
=
61
_JOBREQUEST
.
_serialized_start
=
63
_JOBREQUEST
.
_serialized_end
=
146
_JOBRESPONSE
.
_serialized_start
=
148
_JOBRESPONSE
.
_serialized_end
=
194
_CONTACT
.
_serialized_start
=
196
_CONTACT
.
_serialized_end
=
234
_LICENSE
.
_serialized_start
=
236
_LICENSE
.
_serialized_end
=
272
_INFORESPONSE
.
_serialized_start
=
275
_INFORESPONSE
.
_serialized_end
=
404
_AIM
.
_serialized_start
=
406
_AIM
.
_serialized_end
=
508
# @@protoc_insertion_point(module_scope)
mpai_cae_arp/network/arp_pb2_grpc.py
View file @
51d4ec30
...
...
@@ -15,15 +15,15 @@ class AIMStub(object):
channel: A grpc.Channel.
"""
self
.
getInfo
=
channel
.
unary_unary
(
'/arp.AIM/getInfo'
,
request_serializer
=
arp__pb2
.
InfoRequest
.
SerializeToString
,
response_deserializer
=
arp__pb2
.
InfoResponse
.
FromString
,
)
'/arp.AIM/getInfo'
,
request_serializer
=
arp__pb2
.
InfoRequest
.
SerializeToString
,
response_deserializer
=
arp__pb2
.
InfoResponse
.
FromString
,
)
self
.
work
=
channel
.
unary_stream
(
'/arp.AIM/work'
,
request_serializer
=
arp__pb2
.
JobRequest
.
SerializeToString
,
response_deserializer
=
arp__pb2
.
JobResponse
.
FromString
,
)
'/arp.AIM/work'
,
request_serializer
=
arp__pb2
.
JobRequest
.
SerializeToString
,
response_deserializer
=
arp__pb2
.
JobResponse
.
FromString
,
)
class
AIMServicer
(
object
):
...
...
@@ -48,56 +48,60 @@ class AIMServicer(object):
def
add_AIMServicer_to_server
(
servicer
,
server
):
rpc_method_handlers
=
{
'getInfo'
:
grpc
.
unary_unary_rpc_method_handler
(
servicer
.
getInfo
,
request_deserializer
=
arp__pb2
.
InfoRequest
.
FromString
,
response_serializer
=
arp__pb2
.
InfoResponse
.
SerializeToString
,
),
'work'
:
grpc
.
unary_stream_rpc_method_handler
(
servicer
.
work
,
request_deserializer
=
arp__pb2
.
JobRequest
.
FromString
,
response_serializer
=
arp__pb2
.
JobResponse
.
SerializeToString
,
),
'getInfo'
:
grpc
.
unary_unary_rpc_method_handler
(
servicer
.
getInfo
,
request_deserializer
=
arp__pb2
.
InfoRequest
.
FromString
,
response_serializer
=
arp__pb2
.
InfoResponse
.
SerializeToString
,
),
'work'
:
grpc
.
unary_stream_rpc_method_handler
(
servicer
.
work
,
request_deserializer
=
arp__pb2
.
JobRequest
.
FromString
,
response_serializer
=
arp__pb2
.
JobResponse
.
SerializeToString
,
),
}
generic_handler
=
grpc
.
method_handlers_generic_handler
(
'arp.AIM'
,
rpc_method_handlers
)
server
.
add_generic_rpc_handlers
((
generic_handler
,))
generic_handler
=
grpc
.
method_handlers_generic_handler
(
'arp.AIM'
,
rpc_method_handlers
)
server
.
add_generic_rpc_handlers
((
generic_handler
,
))
# This class is part of an EXPERIMENTAL API.
# This class is part of an EXPERIMENTAL API.
class
AIM
(
object
):
"""Missing associated documentation comment in .proto file."""
@
staticmethod
def
getInfo
(
request
,
target
,
options
=
(),
channel_credentials
=
None
,
call_credentials
=
None
,
insecure
=
False
,
compression
=
None
,
wait_for_ready
=
None
,
timeout
=
None
,
metadata
=
None
):
target
,
options
=
(),
channel_credentials
=
None
,
call_credentials
=
None
,
insecure
=
False
,
compression
=
None
,
wait_for_ready
=
None
,
timeout
=
None
,
metadata
=
None
):
return
grpc
.
experimental
.
unary_unary
(
request
,
target
,
'/arp.AIM/getInfo'
,
arp__pb2
.
InfoRequest
.
SerializeToString
,
arp__pb2
.
InfoResponse
.
FromString
,
options
,
channel_credentials
,
insecure
,
call_credentials
,
compression
,
wait_for_ready
,
timeout
,
metadata
)
arp__pb2
.
InfoRequest
.
SerializeToString
,
arp__pb2
.
InfoResponse
.
FromString
,
options
,
channel_credentials
,
insecure
,
call_credentials
,
compression
,
wait_for_ready
,
timeout
,
metadata
)
@
staticmethod
def
work
(
request
,
target
,
options
=
(),
channel_credentials
=
None
,
call_credentials
=
None
,
insecure
=
False
,
compression
=
None
,
wait_for_ready
=
None
,
timeout
=
None
,
metadata
=
None
):
target
,
options
=
(),
channel_credentials
=
None
,
call_credentials
=
None
,
insecure
=
False
,
compression
=
None
,
wait_for_ready
=
None
,
timeout
=
None
,
metadata
=
None
):
return
grpc
.
experimental
.
unary_stream
(
request
,
target
,
'/arp.AIM/work'
,
arp__pb2
.
JobRequest
.
SerializeToString
,
arp__pb2
.
JobResponse
.
FromString
,
options
,
channel_credentials
,
insecure
,
call_credentials
,
compression
,
wait_for_ready
,
timeout
,
metadata
)
arp__pb2
.
JobRequest
.
SerializeToString
,
arp__pb2
.
JobResponse
.
FromString
,
options
,
channel_credentials
,
insecure
,
call_credentials
,
compression
,
wait_for_ready
,
timeout
,
metadata
)
mpai_cae_arp/time.py
View file @
51d4ec30
"""
This module contains functions to convert time formats. The agreed time format is hh:mm:ss.msc as a string in MPAI standards.
"""
import
datetime
...
...
@@ -93,11 +96,9 @@ def frames_to_seconds(frames: int, fps: int) -> float:
"""
if
fps
<=
0
:
raise
ValueError
(
"The number of frames per second must be greater than 0"
)
raise
ValueError
(
"The number of frames per second must be greater than 0"
)
if
frames
<
0
:
raise
ValueError
(
"The number of frames must be greater than or equal to 0"
)
raise
ValueError
(
"The number of frames must be greater than or equal to 0"
)
return
frames
/
fps
...
...
@@ -126,10 +127,8 @@ def seconds_to_frames(seconds: float, fps: int) -> int:
"""
if
fps
<=
0
:
raise
ValueError
(
"The number of frames per second must be greater than 0"
)
raise
ValueError
(
"The number of frames per second must be greater than 0"
)
if
seconds
<
0
:
raise
ValueError
(
"The number of seconds must be greater than or equal to 0"
)
raise
ValueError
(
"The number of seconds must be greater than or equal to 0"
)
return
int
(
seconds
*
fps
)
mpai_cae_arp/types/__init__.py
View file @
51d4ec30
from
.irregularity
import
Irregularity
,
IrregularityFile
,
IrregularityProperties
,
IrregularityType
from
.restoration
import
Restoration
,
EditingList
from
.
import
schema
__all__
=
[
'Irregularity'
,
'IrregularityFile'
,
'IrregularityProperties'
,
'IrregularityType'
,
'Restoration'
,
'EditingList'
,
'schema'
]
mpai_cae_arp/types/irregularity.py
View file @
51d4ec30
from
typing
import
TypeVar
import
uuid
from
enum
import
Enum
from
pydantic
import
BaseModel
from
pydantic
import
BaseModel
,
Field
from
mpai_cae_arp.audio.standards
import
EqualizationStandard
,
SpeedStandard
from
mpai_cae_arp.files
import
File
,
FileType
from
mpai_cae_arp.time
import
time_to_seconds
class
IrregularityType
(
Enum
):
class
IrregularityType
(
str
,
Enum
):
BRANDS_ON_TAPE
=
"b"
SPLICE
=
"sp"
START_OF_TAPE
=
"sot"
...
...
@@ -22,20 +25,28 @@ class IrregularityType(Enum):
BACKWARD
=
"sb"
class
Source
(
Enum
):
class
Source
(
str
,
Enum
):
AUDIO
=
"a"
VIDEO
=
"v"
BOTH
=
"b"
SelfIrregularity
=
TypeVar
(
"SelfIrregularity"
,
bound
=
"Irregularity"
)
SelfIrregularityProperties
=
TypeVar
(
"SelfIrregularityProperties"
,
bound
=
"IrregularityProperties"
)
SelfIrregularityFile
=
TypeVar
(
"SelfIrregularityFile"
,
bound
=
"IrregularityFile"
)
class
IrregularityProperties
(
BaseModel
):
reading_speed
:
SpeedStandard
reading_equalisation
:
EqualizationStandard
writing_speed
:
SpeedStandard
writing_equalisation
:
EqualizationStandard
reading_speed
:
SpeedStandard
=
Field
(
alias
=
"ReadingSpeedStandard"
)
reading_equalisation
:
EqualizationStandard
=
Field
(
alias
=
"ReadingEqualisationStandard"
)
writing_speed
:
SpeedStandard
=
Field
(
alias
=
"WritingSpeedStandard"
)
writing_equalisation
:
EqualizationStandard
=
Field
(
alias
=
"WritingEqualisationStandard"
)
@
staticmethod
def
from_json
(
json_property
:
dict
):
def
from_json
(
json_property
:
dict
)
->
SelfIrregularityProperties
:
return
IrregularityProperties
(
reading_speed
=
SpeedStandard
(
json_property
[
"ReadingSpeedStandard"
]),
reading_equalisation
=
EqualizationStandard
(
...
...
@@ -44,7 +55,11 @@ class IrregularityProperties(BaseModel):
writing_equalisation
=
EqualizationStandard
(
json_property
[
"WritingEqualisationStandard"
]))
def
to_json
(
self
):
def
to_json
(
self
)
->
dict
:
"""
.. deprecated:: 0.4.0
Use :meth:`IrregularityProperties.json` instead.
"""
return
{
"ReadingSpeedStandard"
:
self
.
reading_speed
.
value
,
"ReadingEqualisationStandard"
:
self
.
reading_equalisation
.
value
,
...
...
@@ -63,16 +78,19 @@ class IrregularityProperties(BaseModel):
class
Irregularity
(
BaseModel
):
irregularity_ID
:
uuid
.
UUID
source
:
Source
time_label
:
str
irregularity_type
:
IrregularityType
|
None
=
None
irregularity_properties
:
IrregularityProperties
|
None
=
None
image_URI
:
str
|
None
=
None
audio_block_URI
:
str
|
None
=
None
irregularity_ID
:
uuid
.
UUID
=
Field
(
default_factory
=
uuid
.
uuid4
,
alias
=
"IrregularityID"
)
source
:
Source
=
Field
(
alias
=
"Source"
)
time_label
:
str
=
Field
(
alias
=
"TimeLabel"
)
irregularity_type
:
IrregularityType
|
None
=
Field
(
default
=
None
,
alias
=
"IrregularityType"
)
irregularity_properties
:
IrregularityProperties
|
None
=
Field
(
default
=
None
,
alias
=
"IrregularityProperties"
)
image_URI
:
str
|
None
=
Field
(
default
=
None
,
alias
=
"ImageURI"
)
audio_block_URI
:
str
|
None
=
Field
(
default
=
None
,
alias
=
"AudioBlockURI"
)
@
staticmethod
def
from_json
(
json_irreg
:
dict
):
def
from_json
(
json_irreg
:
dict
)
->
SelfIrregularity
:
properties
=
None
if
json_irreg
.
get
(
"IrregularityProperties"
)
is
not
None
:
...
...
@@ -82,9 +100,8 @@ class Irregularity(BaseModel):
raw_irreg_type
=
json_irreg
.
get
(
"IrregularityType"
)
irregularity_type
=
None
if
raw_irreg_type
is
not
None
:
if
raw_irreg_type
is
not
(
IrregularityType
.
SPEED
.
value
or
IrregularityType
.
SPEED_AND_EQUALIZATION
.
value
):
if
raw_irreg_type
is
not
(
IrregularityType
.
SPEED
.
value
or
IrregularityType
.
SPEED_AND_EQUALIZATION
.
value
):
irregularity_type
=
IrregularityType
(
raw_irreg_type
)
else
:
if
properties
.
reading_equalisation
!=
properties
.
writing_equalisation
:
...
...
@@ -92,8 +109,7 @@ class Irregularity(BaseModel):
else
:
irregularity_type
=
IrregularityType
.
SPEED
return
Irregularity
(
irregularity_ID
=
uuid
.
UUID
(
json_irreg
[
"IrregularityID"
]),
return
Irregularity
(
irregularity_ID
=
uuid
.
UUID
(
json_irreg
[
"IrregularityID"
]),
source
=
Source
(
json_irreg
[
"Source"
]),
time_label
=
json_irreg
[
"TimeLabel"
],
irregularity_type
=
irregularity_type
,
...
...
@@ -101,7 +117,13 @@ class Irregularity(BaseModel):
image_URI
=
json_irreg
.
get
(
"ImageURI"
),
audio_block_URI
=
json_irreg
.
get
(
"AudioBlockURI"
))
def
to_json
(
self
):
def
to_json
(
self
)
->
dict
:
"""
Returns a dictionary with the irregularity information
.. deprecated:: 0.4.0
Use :func:`Irregularity.json` instead.
"""
dictionary
=
{
"IrregularityID"
:
str
(
self
.
irregularity_ID
),
"Source"
:
self
.
source
.
value
,
...
...
@@ -118,44 +140,16 @@ class Irregularity(BaseModel):
dictionary
[
"AudioBlockURI"
]
=
self
.
audio_block_URI
if
self
.
irregularity_properties
:
dictionary
[
"IrregularityProperties"
]
=
self
.
irregularity_properties
.
to_json
(
)
dictionary
[
"IrregularityProperties"
]
=
self
.
irregularity_properties
.
to_json
(
)
return
dictionary
class
IrregularityFile
(
BaseModel
):
# TODO: the offset calculation is not implemented yet, so it is set to None
irregularities
:
list
[
Irregularity
]
offset
:
int
|
None
=
None
class
Config
:
schema_extra
=
{
"example"
:
{
"offset"
:
0
,
"irregularities"
:
[{
"irregularity_ID"
:
"a0a0a0a0-a0a0-a0a0-a0a0-a0a0a0a0a0a0"
,
"source"
:
"a"
,
"time_label"
:
"00:00:00:00"
,
"irregularity_type"
:
"b"
,
"irregularity_properties"
:
{
"reading_speed"
:
"n"
,
"reading_equalisation"
:
"n"
,
"writing_speed"
:
"n"
,
"writing_equalisation"
:
"n"
},
"audio_block_URI"
:
"https://example.com/audio.wav"
,
}]
}
}
def
__eq__
(
self
,
__o
:
object
)
->
bool
:
if
not
isinstance
(
__o
,
IrregularityFile
):
return
False
...
...
@@ -163,7 +157,7 @@ class IrregularityFile(BaseModel):
return
self
.
irregularities
==
__o
.
irregularities
and
self
.
offset
==
__o
.
offset
@
staticmethod
def
from_json
(
json_irreg
:
dict
):
def
from_json
(
json_irreg
:
dict
)
->
SelfIrregularityFile
:
irregularities
=
[]
for
irreg
in
json_irreg
[
"Irregularities"
]:
...
...
@@ -172,7 +166,7 @@ class IrregularityFile(BaseModel):
return
IrregularityFile
(
irregularities
=
irregularities
,
offset
=
json_irreg
.
get
(
"Offset"
))
def
to_json
(
self
):
def
to_json
(
self
)
->
dict
:
dictionary
=
{
"Irregularities"
:
[
irregularity
.
to_json
()
for
irregularity
in
self
.
irregularities
],
...
...
@@ -183,7 +177,7 @@ class IrregularityFile(BaseModel):
return
dictionary
def
add
(
self
,
irregularity
:
Irregularity
):
def
add
(
self
,
irregularity
:
Irregularity
)
->
SelfIrregularityFile
:
"""Add an irregularity to the list of irregularities.
Parameters
...
...
@@ -197,12 +191,17 @@ class IrregularityFile(BaseModel):
if the irregularity is not a py:class:`Irregularity` object
"""
if
not
isinstance
(
irregularity
,
Irregularity
):
raise
TypeError
(
"IrregularityFile.add() expects an Irregularity object"
)
raise
TypeError
(
"IrregularityFile.add() expects an Irregularity object"
)
self
.
irregularities
.
append
(
irregularity
)
self
.
order
()
return
self
def
join
(
self
,
other
):
"""Append the irregularities of other in current irregularity file.
def
order
(
self
)
->
SelfIrregularityFile
:
self
.
irregularities
.
sort
(
key
=
lambda
x
:
time_to_seconds
(
x
.
time_label
))
return
self
def
join
(
self
,
other
)
->
SelfIrregularityFile
:
"""Append the irregularities of other in current irregularity file, ordered by time.
Parameters
----------
...
...
@@ -217,3 +216,13 @@ class IrregularityFile(BaseModel):
if
not
isinstance
(
other
,
IrregularityFile
):
raise
TypeError
(
"other must be an instance of IrregularityFile"
)
self
.
irregularities
+=
other
.
irregularities
self
.
order
()
return
self
def
save_as_json_file
(
self
,
path
:
str
)
->
None
:
"""
Save the editing list as a JSON file at the given path.
.. versionadded:: 0.4.0
"""
File
(
path
=
path
,
file_type
=
FileType
.
JSON
).
write_content
(
self
.
json
())
mpai_cae_arp/types/restoration.py
0 → 100644
View file @
51d4ec30
import
uuid
from
typing
import
TypeVar
from
pydantic
import
BaseModel
,
Field
from
mpai_cae_arp.audio.standards
import
SpeedStandard
,
EqualizationStandard
from
mpai_cae_arp.files
import
File
,
FileType
class
Restoration
(
BaseModel
):
id
:
uuid
.
UUID
=
Field
(
default_factory
=
uuid
.
uuid4
)
preservation_audio_file_start
:
str
preservation_audio_file_end
:
str
restored_audio_file_URI
:
str
reading_backwards
:
bool
applied_speed_standard
:
SpeedStandard
applied_sample_frequency
:
int
original_equalization_standard
:
EqualizationStandard
Self
=
TypeVar
(
"Self"
,
bound
=
"EditingList"
)
class
EditingList
(
BaseModel
):
"""
.. versionadded:: 0.4.0
"""
original_speed_standard
:
SpeedStandard
original_equalization_standard
:
EqualizationStandard
original_sample_frequency
:
int
restorations
:
list
[
Restoration
]
def
add
(
self
,
restoration
:
Restoration
)
->
Self
:
self
.
restorations
.
append
(
restoration
)
return
self
def
remove
(
self
,
restoration
:
Restoration
)
->
Self
:
self
.
restorations
.
remove
(
restoration
)
return
self
def
remove_by_id
(
self
,
restoration_id
:
uuid
.
UUID
)
->
Self
:
filtered
=
list
(
filter
(
lambda
r
:
r
.
id
!=
restoration_id
,
self
.
restorations
))
self
.
restorations
=
filtered
return
self
def
save_as_json_file
(
self
,
path
:
str
)
->
None
:
File
(
path
=
path
,
file_type
=
FileType
.
JSON
).
write_content
(
self
.
json
())
if
__name__
==
"__main__"
:
rest
=
Restoration
(
preservation_audio_file_start
=
"00:00:00.000"
,
preservation_audio_file_end
=
"00:00:10.000"
,
restored_audio_file_URI
=
"https://www.google.com"
,
reading_backwards
=
False
,
applied_sample_frequency
=
44100
,
applied_speed_standard
=
SpeedStandard
.
III
,
original_equalization_standard
=
EqualizationStandard
.
CCIR
)
editing_list
=
EditingList
(
original_equalization_standard
=
EqualizationStandard
.
CCIR
,
original_speed_standard
=
SpeedStandard
.
III
,
original_sample_frequency
=
44100
,
restorations
=
[])
editing_list
.
add
(
rest
)
print
(
rest
)
print
(
editing_list
.
json
())
mpai_cae_arp/types/schema.py
View file @
51d4ec30
# pylint: disable=too-few-public-methods
from
pydantic
import
BaseModel
,
Field
...
...
@@ -6,12 +7,7 @@ class Contact(BaseModel):
email
:
str
=
Field
(...,
description
=
"Email of the contact person."
)
class
Config
:
schema_extra
=
{
"example"
:
{
"name"
:
"John Doe"
,
"email"
:
"email@email.com"
}
}
schema_extra
=
{
"example"
:
{
"name"
:
"John Doe"
,
"email"
:
"email@email.com"
}}
class
License
(
BaseModel
):
...
...
@@ -33,8 +29,7 @@ class Info(BaseModel):
version
:
str
=
Field
(...,
description
=
"The version of the API."
)
contact
:
Contact
=
Field
(
...,
description
=
"Contact information for the owners of the API."
)
license_info
:
License
=
Field
(
...,
description
=
"License information for the API."
)
license_info
:
License
=
Field
(...,
description
=
"License information for the API."
)
class
Config
:
schema_extra
=
{
...
...
pyproject.toml
View file @
51d4ec30
[tool.poetry]
name
=
"mpai-cae-arp"
version
=
"0.
3.2
"
version
=
"0.
4.0
"
description
=
"The MPAI CAE-ARP software API"
authors
=
[
"Matteo Spanio <dev2@audioinnova.com>"
]
readme
=
"README.md"
...
...
@@ -23,7 +23,6 @@ pytest-cov = "^4.0.0"
pytest-xdist
=
"^3.2.1"
toml
=
"^0.10.2"
[tool.poetry.group.docs.dependencies]
sphinx
=
"^6.1.3"
...
...
@@ -41,16 +40,16 @@ relative_files = true
[tool.yapf]
blank_line_before_nested_class_or_def
=
true
column_limit
=
8
0
column_limit
=
8
8
[tool.pylint]
max-line-length
=
80
max-line-length
=
88
extension-pkg-whitelist
=
['pydantic']
disable
=
[
"C0103"
,
# Invalid name
"C0114"
,
# Missing module docstring
"C0115"
,
# Missing class docstring
"C0116"
,
# Missing function or method docstring
"C0301"
,
# Line too long
"W0102"
,
# Dangerous default value
"E1101"
,
# Module has no member
]
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment