Source code for dscleaner.fileinfo

import soundfile as sf
import tempfile
import os
from .ifileinfo import IFileInfo

[docs]class FileInfo(IFileInfo): """ Defines the class to manipulate soundfiles. Receives a path to a file. Copies the file to a temporary location. Gets edited through the FileUtil. FileWriter converts and writes to another location. NOTE: - close method MUST always be called or else the temporary file stays in disk. - ``with`` statements should be used in order to close the files automatically. """ def __init__(self,path): super().__init__(path) self._path = path #ACTUAL FILE self._tmpPath = tempfile.gettempdir() #TEMPORARY COPY try: import shutil self._tmpPath = shutil.copy(self._path,self._tmpPath) except FileExistsError: print("FEXISTS l28") pass self._initinfo() def __enter__(self): return self def __exit__(self,type,value,traceback): self.close() def _initinfo(self): with sf.SoundFile(self._tmpPath, mode ='r') as rfile: self._samplerate = rfile.samplerate self._frames = self._numchannels = rfile.channels return #================READ METHODS ==================#
[docs] def getFilepath(self): """ See the base class ``ifileinfo``. """ return self._path
[docs] def getNumberOfFrames(self): """ See the base class ``ifileinfo``. """ return len(self.getSamples())
[docs] def getSamplerate(self): """ See the base class ``ifileinfo``. """ return self._samplerate
[docs] def getNumberOfChannels(self): """ Returns: Number of channels the file has. """ return self._numchannels
[docs] def getDuration(self): """ Returns: The duration of the file in seconds. """ return self.getNumberOfFrames()/self.getSamplerate()
[docs] def get_rounded_duration(self): """ Returns: The rounded duration in seconds. """ from math import ceil rounded_duration = ceil(self.getDuration()) #in seconds return rounded_duration
[docs] def getSamples(self): """ Reads all of the samples in the file Returns: numpy array containing the samples. """ return self._frames
#================WRITE METHODS ==================#
[docs] def setSamples(self, samples, samplerate = None): """ Writes the ´samples´ as the new samples in the file. Args: samples: numpy array shaped like (n,c), where c is the number of channels. samplerate: the new sample rate the file will have, if none it will use the initial samplerate. """ if (samplerate == None): samplerate = self.getSamplerate() samples = self._soundfile_array_converter(samples) with sf.SoundFile(self._tmpPath, mode = 'w', samplerate = self.getSamplerate(), channels = self.getNumberOfChannels()) as wfile: wfile.truncate(0) #removes all the samples in the file sf.write(self._tmpPath,samples,samplerate) self._initinfo()
[docs] def truncate(self,num_frames): """ Truncates the file to only have ``num_frames``. """ #with sf.SoundFile(self._tmpPath, mode = 'w', samplerate = self.getSamplerate(), channels = self.getNumChannels()) as wfile: # wfile.truncate(num_frames) self.setSamples(self.getSamples()[:num_frames]) self._initinfo()
[docs] def addSamples(self,samples): """ Appends the samples to the file. Similar to ´setSamples()´ but appends instead of truncating. See the base class ``ifileinfo``. """ samples = self._soundfile_array_converter(samples) with sf.SoundFile(self._tmpPath, mode = 'r+') as wfile:,whence = sf.SEEK_END) wfile.write(samples)
#================MISC METHODS ==================# def _soundfile_array_converter(self,array): """ Checks if it has the correct array shape to be worked by pysoundfile. If not, it will transpose de array. Arguments: array: ndarray to convert. Returns: array: the converted array. """ if(array.shape[1] > 20): #meaning it doesnt represent the number of channelsnumber of channels array = array.T return array
[docs] def close(self): """ Must always be called or the file won't be accessible by other processes AND the temp file will stay in disk. See the base class ``ifileinfo``. """ import os try: os.unlink(self._tmpPath) except expression as identifier: print("err", identifier)