def __init__(self, parent, filter=None): FilterWidget.__init__( self, parent, 'Formats: ', formatColumn, OrderedDict([ (ext, contextData(soundfile.available_formats()[ext], ext)) for ext in sorted(soundfile.available_formats().keys()) ]), ListSelectionWidget, filter) self.name = 'File format'
def cli(input_file, input_text, speed, tone, output_file, output_format, output_subtype, list_formats, list_subtypes, letter_space_factor): if list_formats: for key, value in soundfile.available_formats().items(): click.echo('\x1b[1m{:<10}\x1b[0m {}'.format(key, value)) return if list_subtypes: for key, value in soundfile.available_subtypes(list_subtypes).items(): click.echo('\x1b[1m{:<10}\x1b[0m {}'.format(key, value)) return if not input_text: input_text = input_file.read() options = dict(samplerate=44100, channels=1, subtype=output_subtype, format=output_format) with soundfile.SoundFile(output_file, 'w', **options) as fp: stream_morse_code(fp, input_text, wpm=speed, tone=tone, letter_space_factor=letter_space_factor)
def parseArgs(arg): file = None if arg.split('.')[-1].upper() in sf.available_formats().keys(): file = arg else: file = None return file
def skipIfFormatNotSupported(fmt): fmts = [] if is_module_available("soundfile"): import soundfile fmts = soundfile.available_formats() return skipIf(fmt not in fmts, f'"{fmt}" is not supported by sondfile') return skipIf(True, '"soundfile" not available.')
def __init__(self, filepath, mode="r+", format=None, dtype="int16", **kwargs): self.filepath = filepath self.mode = mode self.dtype = dtype self.file = h5py.File(filepath, mode, **kwargs) if format is None: # filepath = a.flac.h5 -> format = flac second_ext = os.path.splitext(os.path.splitext(filepath)[0])[1] format = second_ext[1:] if format.upper() not in soundfile.available_formats(): # If not found, flac is selected format = "flac" # This format affects only saving self.format = format
def __init__(self, dirPath, scanMode, formats, sampleRates, channels, scanLimits): QtCore.QObject.__init__(self) self.stop = Event() self.dirPath = dirPath self.scanMode = scanMode self.formats = formats self.sampleRates = sampleRates self.channels = channels self.methodList = [] if isinstance(sampleRates, (list, tuple)): self.methodList.append(self.checkSampleRate) if channels: self.methodList.append(self.checkChannels) self.bigger, self.smaller, self.longer, self.shorter = scanLimits if self.bigger and self.smaller: self.methodList.append(self.checkSize) elif self.bigger: self.methodList.append(self.checkSizeBigger) elif self.smaller: self.methodList.append(self.checkSizeSmaller) if self.longer and self.shorter: self.methodList.append(self.checkLength) elif self.longer: self.methodList.append(self.checkLengthLonger) elif self.shorter: self.methodList.append(self.checkLengthShorter) if scanMode: if not isinstance(formats, (list, tuple)): formats = [f for f in soundfile.available_formats().keys()] self.iterator = DirIterator( dirPath, ['*.{}'.format(f) for f in formats], QtCore.QDir.Files, flags=QtCore.QDirIterator.Subdirectories | QtCore.QDirIterator.FollowSymlinks) else: if isinstance(formats, (list, tuple)): self.methodList.insert(0, self.checkFormat) self.iterator = DirIterator( dirPath, QtCore.QDir.Files, flags=QtCore.QDirIterator.Subdirectories | QtCore.QDirIterator.FollowSymlinks)
def __init__(self, location, item_length, target_length, sampling_rate=16000, mono=True, test_stride=100, create_files=True): self.location = Path(location) self.dataset_path = self.location / 'dataset' self.target_length = target_length self.sampling_rate = sampling_rate self.mono = mono self._item_length = item_length self._test_stride = test_stride self._length = 0 self.start_samples = [0] self.train = True self.create_files = create_files try: _ = soundfile.available_formats() except: "print cannot create files, soundfile package not loaded" create_files = False if create_files: if self.dataset_path.exists(): self.files = list_all_audio_files(self.dataset_path) else: unprocessed_files = list_all_audio_files(self.location) self.dataset_path.mkdir() self.create_dataset(unprocessed_files) self.files = list_all_audio_files(self.dataset_path) else: self.files = list_all_audio_files(self.location) self.calculate_length()
def conversion_formats(): '''Lists the formats available for conversion. soundpy uses soundfile to convert files; therefore, whatever available formats soundfile has will be listed here. Examples -------- >>> conversion_formats {'AIFF': 'AIFF (Apple/SGI)', 'AU': 'AU (Sun/NeXT)', 'AVR': 'AVR (Audio Visual Research)', 'CAF': 'CAF (Apple Core Audio File)', 'FLAC': 'FLAC (Free Lossless Audio Codec)', 'HTK': 'HTK (HMM Tool Kit)', 'SVX': 'IFF (Amiga IFF/SVX8/SV16)', 'MAT4': 'MAT4 (GNU Octave 2.0 / Matlab 4.2)', 'MAT5': 'MAT5 (GNU Octave 2.1 / Matlab 5.0)', 'MPC2K': 'MPC (Akai MPC 2k)', 'OGG': 'OGG (OGG Container format)', 'PAF': 'PAF (Ensoniq PARIS)', 'PVF': 'PVF (Portable Voice Format)', 'RAW': 'RAW (header-less)', 'RF64': 'RF64 (RIFF 64)', 'SD2': 'SD2 (Sound Designer II)', 'SDS': 'SDS (Midi Sample Dump Standard)', 'IRCAM': 'SF (Berkeley/IRCAM/CARL)', 'VOC': 'VOC (Creative Labs)', 'W64': 'W64 (SoundFoundry WAVE 64)', 'WAV': 'WAV (Microsoft)', 'NIST': 'WAV (NIST Sphere)', 'WAVEX': 'WAVEX (Microsoft)', 'WVE': 'WVE (Psion Series 3)', 'XI': 'XI (FastTracker 2)'} ''' return sf.available_formats()
'AUDIO_CHANNELS_STEREO', 'AUDIO_CHANNEL_LEFT', 'AUDIO_EAR_LEFT', 'AUDIO_CHANNEL_RIGHT', 'AUDIO_EAR_RIGHT', 'AUDIO_CHANNEL_COUNT', 'AUDIO_EAR_COUNT' ] import numpy as np import soundfile as sf from psychopy.tools.audiotools import * from .exceptions import * # supported formats for loading and saving audio samples to file AUDIO_SUPPORTED_CODECS = [s.lower() for s in sf.available_formats().keys()] # constants for specifying the number of channels AUDIO_CHANNELS_MONO = 1 AUDIO_CHANNELS_STEREO = 2 # constants for indexing channels AUDIO_CHANNEL_LEFT = AUDIO_EAR_LEFT = 0 AUDIO_CHANNEL_RIGHT = AUDIO_EAR_RIGHT = 1 AUDIO_CHANNEL_COUNT = AUDIO_EAR_COUNT = 2 class AudioClip: """Class for storing audio clip data. This class is used to store and handle raw audio data, such as those
action="store_true", dest="list_supported_types", help="List all supported input file types and then exit", default=False) parser.add_option( "--output_name", dest="output_name", help="Output name added to decorations if not on command line", type="string", default="") (options, args) = parser.parse_args() if options.list_supported_types: print('Supported file types:\n') for file_type, desc in sf.available_formats().items(): print('{} - {}'.format(file_type, desc)) sys.exit(0) if len(args) > 0 and options.input_file_stat: print_inputfile_stats(args[0]) sys.exit(0) if len(args) < 1: print( "Error in command line parameters. Run this program with --help for help." ) sys.exit(1) elif len(args) == 1: outputfile = "" else:
from matplotlib.backends.backend_gtk3cairo import FigureCanvasGTK3Cairo as FigureCanvas from matplotlib.backends.backend_gtk3 import NavigationToolbar2GTK3 as NavigationToolbar song_pool = ["/home/vex/Music", "."] curr_list = [ "example.flac", ] playlists = ["My First Playlist", "Awesome Mixtape", "Chill Ambience Tracks"] # Get files and folders for tgt in song_pool: print("In", tgt) for url, fldr, rsrc in fetch_dir(tgt): for r in rsrc: i, ext = get_ext(r) if ext[1:].upper() in sf.available_formats(): print("\t", url, "/", r) # Get Metadata mtdt = mt.File(curr_list[0]) print(mtdt.info.pprint()) print(mtdt.tags.pprint()) print(mtdt.pictures) # Play Audio data, srate = sf.read(curr_list[0], dtype='float32') comfirm = input("Play song? ") sd.play(data, srate) """ # Draw Spectrum
def is_valid_sf(f): return any(f.lower().endswith(ending.lower()) for ending in sf.available_formats())
def _formats(): # Get a list of the formats supported by the soundfile lib. names = soundfile.available_formats().iterkeys() return [FORMATS[n] for n in names if n in FORMATS]
gi.require_version("Gtk", "3.0") gi.require_version('GdkPixbuf', '2.0') gi.require_version('Gst', '1.0') from gi.repository import Gtk as g from gi.repository import GdkPixbuf as gpix from gi.repository import Gst as gst gst.init(None) def time_convert(nanosec): pass ## Finding what file extensions/formats we can read. This is the only part using soundfile until someone figures out a way to parse the available GStreamer plugins. formats = list(sf.available_formats().keys() ) # + ["MP3", ] This will make it take a long time to load. # from https://github.com/GStreamer/gstreamer/blob/master/tools/gst-inspect.c # features = gst_registry_get_feature_list_by_plugin (gst_registry_get (), # feature = GST_PLUGIN_FEATURE (features->data); # factory = GST_ELEMENT_FACTORY (feature); # factory = GST_TYPE_FIND_FACTORY (feature); # extensions = gst_type_find_factory_get_extensions (factory); # https://lazka.github.io/pgi-docs/#Gst-1.0/classes/Registry.html#Gst.Registry #plugin_reg = gst.Registry().get() #for each in plugin_reg.get_plugin_list(): # each.get_description() # gst.TypeFindFactory # each.list_free()
Parameters ---------- level : str or int The desired temporary logging level. For allowed values see: https://docs.python.org/2/library/logging.html#logging-levels ''' logger = logging.getLogger() current_level = logger.level logger.setLevel(level) yield logger.setLevel(current_level) # TODO: this needs some formalization AUDIO_FORMATS = {f.lower() for f in soundfile.available_formats()} AUDIO_FORMATS |= {'m4a', 'mp3'} def _get_sorted_files(folder_path, max_depth=None): ''' Return a list of absolute paths to all valid files contained within the folder specified by ```folder_path```. Parameters ---------- folder_path : str Path to the folder to scan for files. Returns -------
def test_available_formats(): formats = sf.available_formats() assert 'WAV' in formats assert 'OGG' in formats assert 'FLAC' in formats
def __init__(self, parent, dirName=None): QtWidgets.QDialog.__init__(self, parent) uic.loadUi('{}/scanoptions.ui'.format(os.path.dirname(utils.__file__)), self) if dirName: self.dirPathEdit.setText(dirName) else: self.dirNameFrame.setVisible(False) self.browseBtn.clicked.connect(self.browse) self.allFormatsChk.setChecked(True) self.allFormatsChk.toggled.connect(self.toggleAllFormats) self.formatModel = QtGui.QStandardItemModel() self.formatModel.dataChanged.connect(self.checkAllFormatsFromModel) self.formatList.setModel(self.formatModel) for ext in sorted(soundfile.available_formats().keys()): format = soundfile.available_formats()[ext] item = QtGui.QStandardItem(format) item.setData(ext, FormatRole) item.setCheckable(True) item.setCheckState(QtCore.Qt.Checked) self.formatModel.appendRow(item) self.allSampleRatesChk.setChecked(True) self.allSampleRatesChk.toggled.connect(self.toggleAllSampleRates) self.sampleRatesModel = QtGui.QStandardItemModel() self.sampleRatesModel.dataChanged.connect( self.checkAllSampleRatesFromModel) self.sampleRatesList.setModel(self.sampleRatesModel) for sr in (192000, 176400, 96000, 88200, 48000, 44100, 32000, 22050, 16000, 8000): item = QtGui.QStandardItem('{:.1f} kHz'.format(sr / 1000.)) item.setData(sr, FormatRole) item.setCheckable(True) item.setCheckState(QtCore.Qt.Checked) self.sampleRatesModel.appendRow(item) self.okBtn = self.buttonBox.button(self.buttonBox.Ok) self.okBtn.setText('Scan') self.currentSizeBiggerUnit = self.sizeBiggerCombo.currentIndex() self.currentSizeSmallerUnit = self.sizeSmallerCombo.currentIndex() self.sizeBiggerChk.toggled.connect( lambda state: self.checkSizeIntegrity('Smaller') if state else None) self.sizeBiggerSpin.valueChanged.connect( lambda *args: self.checkSizeIntegrity('Bigger')) self.sizeBiggerCombo.currentIndexChanged.connect( lambda *args: self.checkSizeIntegrity('Bigger')) self.sizeSmallerChk.toggled.connect( lambda state: self.checkSizeIntegrity('Bigger') if state else None) self.sizeSmallerSpin.valueChanged.connect( lambda *args: self.checkSizeIntegrity('Smaller')) self.sizeSmallerCombo.currentIndexChanged.connect( lambda *args: self.checkSizeIntegrity('Smaller')) self.currentLengthLongerUnit = self.lengthLongerCombo.currentIndex() self.currentLengthShorterUnit = self.lengthShorterCombo.currentIndex() self.lengthLongerChk.toggled.connect( lambda state: self.checkLengthIntegrity('Shorter') if state else None) self.lengthLongerSpin.valueChanged.connect( lambda *args: self.checkLengthIntegrity('Longer')) self.lengthLongerCombo.currentIndexChanged.connect( lambda *args: self.checkLengthIntegrity('Longer')) self.lengthShorterChk.toggled.connect( lambda state: self.checkLengthIntegrity('Longer') if state else None) self.lengthShorterSpin.valueChanged.connect( lambda *args: self.checkLengthIntegrity('Shorter')) self.lengthShorterCombo.currentIndexChanged.connect( lambda *args: self.checkLengthIntegrity('Shorter'))
def __init__(self, parent=None): QtWidgets.QWidget.__init__(self, parent) self._length = 0 self._lengthFormat = self.LengthFormat.Secs self._showMSecs = True self._showMSecsTrailingZeros = True self._maxNumWidth = max(self.fontMetrics().width(str(n)) for n in range(10)) self.setSizePolicy( QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Expanding)) headerSizePolicy = QtWidgets.QSizePolicy( QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) valueSizePolicy = QtWidgets.QSizePolicy( QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Preferred) mainLayout = QtWidgets.QHBoxLayout() mainLayout.setContentsMargins(0, 0, 0, 0) self.setLayout(mainLayout) self.tabWidget = QtWidgets.QTabWidget() mainLayout.addWidget(self.tabWidget) self.infoTab = QtWidgets.QWidget() self.infoTab.setSizePolicy( QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Maximum)) self.tabWidget.addTab(self.infoTab, 'Info') infoLayout = QtWidgets.QGridLayout() self.infoTab.setLayout(infoLayout) self.infoFileNameLbl = EllipsisLabel() infoLayout.addWidget(self.infoFileNameLbl, 0, 0, 1, 5) lengthLbl = QtWidgets.QLabel('Length:') lengthLbl.setSizePolicy(headerSizePolicy) infoLayout.addWidget(lengthLbl, 1, 0) self.infoLengthLbl = QtWidgets.QLabel() self.infoLengthLbl.setSizePolicy(valueSizePolicy) infoLayout.addWidget(self.infoLengthLbl, 1, 1) infoLayout.addItem( QtWidgets.QSpacerItem(16, 8, QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed), 1, 2) formatLbl = QtWidgets.QLabel('Format:') formatLbl.setSizePolicy(headerSizePolicy) infoLayout.addWidget(formatLbl, 1, 3) self.infoFormatLbl = QtWidgets.QLabel() self.infoFormatLbl.setFixedWidth( max([ self.fontMetrics().width(fmt) for fmt in soundfile.available_formats().keys() ])) infoLayout.addWidget(self.infoFormatLbl, 1, 4) sampleRateLbl = QtWidgets.QLabel('Rate:') sampleRateLbl.setSizePolicy(headerSizePolicy) infoLayout.addWidget(sampleRateLbl, 2, 0) self.infoSampleRateLbl = QtWidgets.QLabel() infoLayout.addWidget(self.infoSampleRateLbl, 2, 1) channelsLbl = QtWidgets.QLabel('Chans:') channelsLbl.setSizePolicy(headerSizePolicy) infoLayout.addWidget(channelsLbl, 2, 3) self.infoChannelsLbl = QtWidgets.QLabel() self.infoChannelsLbl.setFixedWidth(self._maxNumWidth * 2) infoLayout.addWidget(self.infoChannelsLbl, 2, 4) self.tagsWidget = QtWidgets.QWidget() self.tagsWidget.setSizePolicy( QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Maximum)) self.tabWidget.addTab(self.tagsWidget, 'Tags') tagsLayout = QtWidgets.QHBoxLayout() self.tagsWidget.setLayout(tagsLayout) self.tagsEdit = TagsEditorTextEdit() self.tagsEdit.setSizePolicy( QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Ignored, QtWidgets.QSizePolicy.Ignored)) tagsLayout.addWidget(self.tagsEdit) self.tagsEdit.setApplyMode(True) self.tagsEdit.tagsApplied.connect(self.tagsApplied.emit) self.tabWidget.setTabEnabled(1, False) self.infoTab.setEnabled(False) self.resetLengthWidth() self.clear()
def __init__(self, parent=None): QtWidgets.QWidget.__init__(self, parent) layout = QtWidgets.QGridLayout() self.setLayout(layout) layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(QtWidgets.QLabel('Name:'), 0, 0) self.nameSearchEdit = FilterLineEdit() self.nameSearchEdit.textChanged.connect(self.textSearchChanged) layout.addWidget(self.nameSearchEdit, 0, 1, 1, 2) layout.addWidget(QtWidgets.QLabel('Filters:'), 1, 0) self.filterWidget = FilterContainer() self.filterWidget.filtersChanged.connect(self.updateFilters) self.filterData = [] layout.addWidget(self.filterWidget, 1, 1) self.addFilterBtn = HoverDecorator(QtWidgets.QToolButton)() self.addFilterBtn.setHoverText('Add search filters') self.addFilterBtn.setText('+') self.addFilterBtn.setAutoRaise(True) self.addFilterBtn.setArrowType(QtCore.Qt.NoArrow) self.addFilterBtn.setStyleSheet( 'QToolButton::menu-indicator {image:none;}') self.addFilterBtn.setPopupMode(self.addFilterBtn.InstantPopup) layout.addWidget(self.addFilterBtn, 1, 2) self.filterMenu = QtWidgets.QMenu(self) self.filterMenu.aboutToShow.connect(self.checkMenuFilters) self.addFilterBtn.setMenu(self.filterMenu) self.hoverWidgets = [ self.nameSearchEdit, self.filterWidget, self.addFilterBtn ] formatMenu = self.filterMenu.addMenu('Formats') formatMenu.menuAction().setData(FormatFilterWidget) formatMenu.addAction('Custom filter', lambda: self.filterWidget.addFilter('format')) formatSeparator = formatMenu.addAction('Format templates') formatSeparator.setSeparator(True) for ext in sorted(soundfile.available_formats().keys()): formatMenu.addAction( soundfile.available_formats()[ext], lambda ext=ext: self.filterWidget.addFilter('format', [ext])) addLengthAction = self.filterMenu.addAction( 'Length', lambda: self.filterWidget.addFilter('lengthRange')) addLengthAction.setData(LengthRangeFilterWidget) sampleRateMenu = self.filterMenu.addMenu('Sample rate') sampleRateMenu.menuAction().setData(SampleRateFilterWidget) sampleRateMenu.addAction( 'Sample rate range', lambda: self.filterWidget.addFilter('sampleRateRange')) sampleRateMenu.addAction( 'Custom filter', lambda: self.filterWidget.addFilter('sampleRate')) sampleRateSeparator = sampleRateMenu.addAction('Sample rate templates') sampleRateSeparator.setSeparator(True) for sr in sampleRatesList: sampleRateMenu.addAction( '{:.1f} kHz'.format(sr / 1000.), lambda sr=sr: self.filterWidget.addFilter('sampleRate', [sr])) channelsMenu = self.filterMenu.addMenu('Channels') channelsMenu.menuAction().setData(ChannelsFilterWidget) channelsMenu.addAction('Custom filter', lambda: self.filterWidget.addFilter('channels')) channelsSeparator = channelsMenu.addAction('Channels templates') channelsSeparator.setSeparator(True) for ch in sorted(channelsLabels.keys()): channelsMenu.addAction( '{}: {}'.format(ch, channelsLabels[ch]), lambda ch=ch: self.filterWidget.addFilter('channels', [ch])) layout.setColumnStretch(1, 100)
from __future__ import print_function import soundfile as sf print("PySoundFile version: {}".format(sf.__version__)) for key, val in sf.available_formats().items(): print("{:5s} -- desc: {}".format(key, val))
"""A Unix pipe-style command-line interface for audio processing. This utility is inspired by imagepipe: https://github.com/pallets/click/blob/master/examples/imagepipe/imagepipe.py """ from importlib import import_module import os import click import soundfile as sf from .utils import processor, generator from .filetypes import SimpleFile from ..data.datatype import Audio SOUNDFILE_FORMAT = tuple(sf.available_formats().keys()) SPH2PIPE_FORMAT = 'WV1', 'WV2', 'SPH' LISTING_FORMAT = 'LST', 'NDX', 'TXT' SUPPORTED_FEATURE = 'STFT', 'CQT', 'GAMMATONE', 'MFCC',\ 'MELSPEC', 'PNCC', 'PNSPEC', 'MODSPEC' cur_dir = os.path.dirname(__file__) EXTRACT_CFG = os.path.abspath(f'{cur_dir}/../cfg/audpipe/extract.ini') MAXNFRAME_SHOW = 1000 @click.group(chain=True) def cli(): """audpipe: Batch-process AUDio through audlib in a PIPEline. Chain commands in any sensible sequence, starting with `open`.
from PyQt5 import QtCore import soundfile availableFormats = tuple(f.lower() for f in soundfile.available_formats().keys()) availableExtensionsDot = [] availableExtensionsWildcard = [] for f in availableFormats: availableExtensionsDot.append('.' + f) availableExtensionsWildcard.append('*.' + f) availableExtensionsWildcard = tuple('*.' + f for f in availableFormats) availableExtensionsDot = tuple('*.' + f for f in availableFormats) sampleRatesList = (192000, 176400, 96000, 88200, 48000, 44100, 32000, 22050, 16000, 8000) subtypesDict = { 'FLOAT': '32f', 'DOUBLE': '64f', 'DPCM_16': '16', 'PCM_S8': 'S8', 'ALAC_24': '24', 'DWVW_12': '12', 'PCM_U8': 'U8', 'ALAC_32': '32', 'PCM_32': '32', 'ALAC_16': '16', 'ALAC_20': '20', 'DWVW_16': '16', 'DWVW_24': '24', 'DPCM_8': '8',
def test_available_formats(): formats = sf.available_formats() assert 'WAV' in formats assert 'OGG' in formats assert 'FLAC' in formats
PARSER = flag.ArgumentParser( prog='sapfy', description="Spotify daemon intended to sap spotify's songs as they play.") PARSER.add_argument('-v', action='store_const', help='Enables verbose output', const=l.DEBUG, default=l.INFO) PARSER.add_argument('-f', '--format', default='FLAC', metavar='<audio file extension>', help='Audio format of the output file', choices=sf.available_formats().keys()) PARSER.add_argument( '-o', '--output', default='{albumArtist[0]}/{album}/{trackNumber} {title}', help='A string with formatting placeholders like artist and title and etc. ' 'See documentation for more information. The path is relative to the ' 'target folder.') PARSER.add_argument('-t', '--target', default='./', help='The target folder where the musics go') PARSER.add_argument( '-s', '--strict-length', nargs='?',
import numpy as np import soundfile as sf # TODO @blisc: Perhaps refactor instead of import guarding HAVE_KALDI_PYDUB = True try: from kaldiio.matio import read_kaldi from kaldiio.utils import open_like_kaldi from pydub import AudioSegment as Audio from pydub.exceptions import CouldntDecodeError except ModuleNotFoundError: HAVE_KALDI_PYDUB = False from nemo.utils import logging available_formats = sf.available_formats() sf_supported_formats = ["." + i.lower() for i in available_formats.keys()] class AudioSegment(object): """Monaural audio segment abstraction. :param samples: Audio samples [num_samples x num_channels]. :type samples: ndarray.float32 :param sample_rate: Audio sample rate. :type sample_rate: int :raises TypeError: If the sample data type is not float or int. """ def __init__(self, samples, sample_rate, target_sr=None,
class PathWrapper: primary_formats = set("." + key.lower() for key in sf.available_formats().keys()) secondary_formats = {".m4a", ".mp3"} if PY_DUB_ENABLED else set() supported_formats = primary_formats | secondary_formats supported_formats = supported_formats | set(key.upper() for key in supported_formats) # re_match_pattern = "$|".join(final_supported_formats) # subtypes = soundfile.available_subtypes() logger.debug(f"Available formats: {supported_formats}") # Considering idx 0 to always be step out! def __init__(self, path: str = "./"): self.current_path = pathlib.Path(path).absolute() self.audio_file_list: List[pathlib.Path] = [] self.folder_list: List[pathlib.Path] = [] def list_audio(self) -> Generator[pathlib.Path, None, None]: yield from (path_obj for path_obj in self.list_file() if path_obj.suffix in self.supported_formats) def list_folder(self) -> Generator[pathlib.Path, None, None]: """ First element will be current folder location. either use next() or list()[1:] to skip it. """ yield self.current_path.parent yield from (path_ for path_ in self.current_path.iterdir() if path_.is_dir()) def list_file(self) -> Generator[pathlib.Path, None, None]: """ Can't use glob as it match folders such as .git, using pathlib.Path object instead. """ yield from (item for item in self.current_path.iterdir() if item.is_file()) def step_in(self, directory_idx: int): """ Relative / Absolute paths supported. """ try: self.current_path = self.folder_list[directory_idx] except IndexError as err: raise NotADirectoryError( f"Directory index {directory_idx} does not exist!") from err self.refresh_list() return self.current_path def step_out(self): if self.current_path == self.current_path.parent: return self.current_path self.current_path = self.current_path.parent self.refresh_list() return self.current_path def refresh_list(self): self.audio_file_list.clear() self.folder_list.clear() self.audio_file_list.extend(self.list_audio()) self.folder_list.extend(self.list_folder()) def fetch_meta(self): # This might have to deal the cases such as path changing before generator fires up. for file_dir in self.list_audio(): yield TinyTag.get(file_dir) def fetch_tag_data(self): for file_dir in self.list_audio(): yield TinyTag.get(file_dir) def __len__(self): return len(self.folder_list) + len(self.audio_file_list) def __getitem__(self, item: int): # logger.debug(f"idx: {item}, len_f: {len(self.folder_list)}, len_a: {len(self.audio_file_list)}") try: return self.folder_list[item] except IndexError as err: if len(self) == 0: raise IndexError( "No file or folder to index in current directory." ) from err return self.audio_file_list[item - len(self.folder_list)] def index(self, target: Union[str, pathlib.Path]): path_ = pathlib.Path(target) try: return len(self.folder_list) + self.audio_file_list.index(path_) except ValueError as err: raise IndexError( f"Cannot find given target '{path_.as_posix()}'!") from err