chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 12:40:42 +08:00
commit e25996e7db
15472 changed files with 3536181 additions and 0 deletions
+18
View File
@@ -0,0 +1,18 @@
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from .esc50 import ESC50
from .tess import TESS
__all__ = ["ESC50", "TESS"]
+98
View File
@@ -0,0 +1,98 @@
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import annotations
import paddle
from ..features import MFCC, LogMelSpectrogram, MelSpectrogram, Spectrogram
feat_funcs = {
'raw': None,
'melspectrogram': MelSpectrogram,
'mfcc': MFCC,
'logmelspectrogram': LogMelSpectrogram,
'spectrogram': Spectrogram,
}
class AudioClassificationDataset(paddle.io.Dataset):
"""
Base class of audio classification dataset.
"""
def __init__(
self,
files: list[str],
labels: list[int],
feat_type: str = 'raw',
sample_rate: int | None = None,
**kwargs,
):
"""
Args:
files (:obj:`List[str]`): A list of absolute path of audio files.
labels (:obj:`List[int]`): Labels of audio files.
feat_type (:obj:`str`, `optional`, defaults to `raw`):
It identifies the feature type that user wants to extract an audio file.
"""
super().__init__()
if feat_type not in feat_funcs.keys():
raise RuntimeError(
f"Unknown feat_type: {feat_type}, it must be one in {list(feat_funcs.keys())}"
)
self.files = files
self.labels = labels
self.feat_type = feat_type
self.sample_rate = sample_rate
self.feat_config = (
kwargs # Pass keyword arguments to customize feature config
)
def _get_data(self, input_file: str):
raise NotImplementedError
def _convert_to_record(self, idx):
file, label = self.files[idx], self.labels[idx]
waveform, sample_rate = paddle.audio.load(file)
self.sample_rate = sample_rate
feat_func = feat_funcs[self.feat_type]
record = {}
if len(waveform.shape) == 2:
waveform = waveform.squeeze(0) # 1D input
waveform = paddle.to_tensor(waveform, dtype=paddle.float32)
if feat_func is not None:
waveform = waveform.unsqueeze(0) # (batch_size, T)
if self.feat_type != 'spectrogram':
feature_extractor = feat_func(
sr=self.sample_rate, **self.feat_config
)
else:
feature_extractor = feat_func(**self.feat_config)
record['feat'] = feature_extractor(waveform).squeeze(0)
else:
record['feat'] = waveform
record['label'] = label
return record
def __getitem__(self, idx):
record = self._convert_to_record(idx)
return record['feat'], record['label']
def __len__(self):
return len(self.files)
+227
View File
@@ -0,0 +1,227 @@
# Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import annotations
import os
from typing import TYPE_CHECKING, Any, Literal, NamedTuple, TypeAlias
from paddle.dataset.common import DATA_HOME
from paddle.utils import download
from .dataset import AudioClassificationDataset
if TYPE_CHECKING:
_ModeLiteral: TypeAlias = Literal[
'train',
'dev',
]
_FeatTypeLiteral: TypeAlias = Literal[
'raw',
'melspectrogram',
'mfcc',
'logmelspectrogram',
'spectrogram',
]
__all__ = []
class ESC50(AudioClassificationDataset):
"""
The ESC-50 dataset is a labeled collection of 2000 environmental audio recordings
suitable for benchmarking methods of environmental sound classification. The dataset
consists of 5-second-long recordings organized into 50 semantical classes (with
40 examples per class)
Reference:
ESC: Dataset for Environmental Sound Classification
http://dx.doi.org/10.1145/2733373.2806390
Args:
mode (str, optional): It identifies the dataset mode (train or dev). Default:train.
split (int, optional): It specify the fold of dev dataset. Default:1.
feat_type (str, optional): It identifies the feature type that user wants to extract of an audio file. Default:raw.
archive(dict, optional): it tells where to download the audio archive. Default:None.
Returns:
:ref:`api_paddle_io_Dataset`. An instance of ESC50 dataset.
Examples:
.. code-block:: pycon
>>> # doctest: +TIMEOUT(60)
>>> import paddle
>>> esc50_dataset = paddle.audio.datasets.ESC50(
... mode='dev',
... feat_type='raw',
... )
>>> for idx in range(5):
... audio, label = esc50_dataset[idx]
... # do something with audio, label
... print(audio.shape, label)
... # [audio_data_length] , label_id
paddle.Size([220500]) 0
paddle.Size([220500]) 14
paddle.Size([220500]) 36
paddle.Size([220500]) 36
paddle.Size([220500]) 19
>>> esc50_dataset = paddle.audio.datasets.ESC50(
... mode='dev',
... feat_type='mfcc',
... n_mfcc=40,
... )
>>> for idx in range(5):
... audio, label = esc50_dataset[idx]
... # do something with mfcc feature, label
... print(audio.shape, label)
... # [feature_dim, length] , label_id
paddle.Size([40, 1723]) 0
paddle.Size([40, 1723]) 14
paddle.Size([40, 1723]) 36
paddle.Size([40, 1723]) 36
paddle.Size([40, 1723]) 19
"""
archive: dict[str, str] = {
'url': 'https://paddleaudio.bj.bcebos.com/datasets/ESC-50-master.zip',
'md5': '7771e4b9d86d0945acce719c7a59305a',
}
label_list: list[str] = [
# Animals
'Dog',
'Rooster',
'Pig',
'Cow',
'Frog',
'Cat',
'Hen',
'Insects (flying)',
'Sheep',
'Crow',
# Natural soundscapes & water sounds
'Rain',
'Sea waves',
'Crackling fire',
'Crickets',
'Chirping birds',
'Water drops',
'Wind',
'Pouring water',
'Toilet flush',
'Thunderstorm',
# Human, non-speech sounds
'Crying baby',
'Sneezing',
'Clapping',
'Breathing',
'Coughing',
'Footsteps',
'Laughing',
'Brushing teeth',
'Snoring',
'Drinking, sipping',
# Interior/domestic sounds
'Door knock',
'Mouse click',
'Keyboard typing',
'Door, wood creaks',
'Can opening',
'Washing machine',
'Vacuum cleaner',
'Clock alarm',
'Clock tick',
'Glass breaking',
# Exterior/urban noises
'Helicopter',
'Chainsaw',
'Siren',
'Car horn',
'Engine',
'Train',
'Church bells',
'Airplane',
'Fireworks',
'Hand saw',
]
meta: str = os.path.join('ESC-50-master', 'meta', 'esc50.csv')
audio_path: str = os.path.join('ESC-50-master', 'audio')
class meta_info(NamedTuple):
filename: str
fold: str
target: str
category: str
esc10: str
src_file: str
take: str
def __init__(
self,
mode: _ModeLiteral = 'train',
split: int = 1,
feat_type: _FeatTypeLiteral = 'raw',
archive: dict[str, str] | None = None,
**kwargs: Any,
) -> None:
assert split in range(1, 6), (
f'The selected split should be integer, and 1 <= split <= 5, but got {split}'
)
if archive is not None:
self.archive = archive
files, labels = self._get_data(mode, split)
super().__init__(
files=files, labels=labels, feat_type=feat_type, **kwargs
)
def _get_meta_info(self) -> list[meta_info]:
ret = []
with open(os.path.join(DATA_HOME, self.meta), 'r') as rf:
for line in rf.readlines()[1:]:
ret.append(self.meta_info(*line.strip().split(',')))
return ret
def _get_data(
self, mode: _ModeLiteral, split: int
) -> tuple[list[str], list[int]]:
if not os.path.isdir(
os.path.join(DATA_HOME, self.audio_path)
) or not os.path.isfile(os.path.join(DATA_HOME, self.meta)):
download.get_path_from_url(
self.archive['url'],
DATA_HOME,
self.archive['md5'],
decompress=True,
)
meta_info = self._get_meta_info()
files = []
labels = []
for sample in meta_info:
filename, fold, target, _, _, _, _ = sample
if mode == 'train' and int(fold) != split:
files.append(os.path.join(DATA_HOME, self.audio_path, filename))
labels.append(int(target))
if mode != 'train' and int(fold) == split:
files.append(os.path.join(DATA_HOME, self.audio_path, filename))
labels.append(int(target))
return files, labels
+166
View File
@@ -0,0 +1,166 @@
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import annotations
import os
from typing import TYPE_CHECKING, Any, NamedTuple
from paddle.dataset.common import DATA_HOME
from paddle.utils import download
from .dataset import AudioClassificationDataset
if TYPE_CHECKING:
from .esc50 import _FeatTypeLiteral, _ModeLiteral
__all__ = []
class TESS(AudioClassificationDataset):
"""
TESS is a set of 200 target words were spoken in the carrier phrase
"Say the word _____' by two actresses (aged 26 and 64 years) and
recordings were made of the set portraying each of seven emotions(anger,
disgust, fear, happiness, pleasant surprise, sadness, and neutral).
There are 2800 stimuli in total.
Reference:
Toronto emotional speech set (TESS) https://tspace.library.utoronto.ca/handle/1807/24487
https://doi.org/10.5683/SP2/E8H2MF
Args:
mode (str, optional): It identifies the dataset mode (train or dev). Defaults to train.
n_folds (int, optional): Split the dataset into n folds. 1 fold for dev dataset and n-1 for train dataset. Defaults to 5.
split (int, optional): It specify the fold of dev dataset. Defaults to 1.
feat_type (str, optional): It identifies the feature type that user wants to extract of an audio file. Defaults to raw.
archive(dict): it tells where to download the audio archive. Defaults to None.
Returns:
:ref:`api_paddle_io_Dataset`. An instance of TESS dataset.
Examples:
.. code-block:: pycon
>>> # doctest: +TIMEOUT(60)
>>> import paddle
>>> tess_dataset = paddle.audio.datasets.TESS(
... mode='dev',
... feat_type='raw',
... )
>>> for idx in range(5):
... audio, label = tess_dataset[idx]
... # do something with audio, label
... print(audio.shape, label)
... # [audio_data_length] , label_id
>>> tess_dataset = paddle.audio.datasets.TESS(
... mode='dev',
... feat_type='mfcc',
... n_mfcc=40,
... )
>>> for idx in range(5):
... audio, label = tess_dataset[idx]
... # do something with mfcc feature, label
... print(audio.shape, label)
... # [feature_dim, num_frames] , label_id
"""
archive: dict[str, str] = {
'url': 'https://bj.bcebos.com/paddleaudio/datasets/TESS_Toronto_emotional_speech_set.zip',
'md5': '1465311b24d1de704c4c63e4ccc470c7',
}
label_list: list[str] = [
'angry',
'disgust',
'fear',
'happy',
'neutral',
'ps', # pleasant surprise
'sad',
]
audio_path: str = 'TESS_Toronto_emotional_speech_set'
class meta_info(NamedTuple):
speaker: str
word: str
emotion: str
def __init__(
self,
mode: _ModeLiteral = 'train',
n_folds: int = 5,
split: int = 1,
feat_type: _FeatTypeLiteral = 'raw',
archive: dict[str, str] | None = None,
**kwargs: Any,
) -> None:
assert isinstance(n_folds, int) and (n_folds >= 1), (
f'the n_folds should be integer and n_folds >= 1, but got {n_folds}'
)
assert split in range(1, n_folds + 1), (
f'The selected split should be integer and should be 1 <= split <= {n_folds}, but got {split}'
)
if archive is not None:
self.archive = archive
files, labels = self._get_data(mode, n_folds, split)
super().__init__(
files=files, labels=labels, feat_type=feat_type, **kwargs
)
def _get_meta_info(self, files) -> list[meta_info]:
ret = []
for file in files:
basename_without_extend = os.path.basename(file)[:-4]
ret.append(self.meta_info(*basename_without_extend.split('_')))
return ret
def _get_data(
self, mode: str, n_folds: int, split: int
) -> tuple[list[str], list[int]]:
if not os.path.isdir(os.path.join(DATA_HOME, self.audio_path)):
download.get_path_from_url(
self.archive['url'],
DATA_HOME,
self.archive['md5'],
decompress=True,
)
wav_files = []
for root, _, files in os.walk(os.path.join(DATA_HOME, self.audio_path)):
for file in files:
if file.endswith('.wav'):
wav_files.append(os.path.join(root, file))
meta_info = self._get_meta_info(wav_files)
files = []
labels = []
for idx, sample in enumerate(meta_info):
_, _, emotion = sample
target = self.label_list.index(emotion)
fold = idx % n_folds + 1
if mode == 'train' and int(fold) != split:
files.append(wav_files[idx])
labels.append(target)
if mode != 'train' and int(fold) == split:
files.append(wav_files[idx])
labels.append(target)
return files, labels