Esempio n. 1
0
    def convert_to_pcm(self,
                       sound_path,
                       tmp_directory,
                       force_use_ffmpeg=False,
                       mono=False):
        """
        Convert a given sound file to PCM. By default we first try to use corresponding decoders for each format and
        preserve original file properties (sampling rate, etc). If conversion fails with this method we failback to
        ffmpeg conversion and set standartized 44.1kHz, 16bit output. ffmpeg conversion still preserves number of
        channels but can be optionally set to output a mono file (useful for analysis code)
        :param sound_path: path of the audiofile to convert
        :param force_use_ffmpeg: don't try to use format specific decoder and go straight to ffmpeg
        :param mono: output mono file (only applies when using ffmpeg conversion)
        :return: path of the converted audio file
        """
        # Convert to PCM and save PCM version in `tmp_wavefile`
        try:
            fh, tmp_wavefile = tempfile.mkstemp(suffix=".wav",
                                                prefix="%i_" % self.sound.id,
                                                dir=tmp_directory)
            # Close file handler as we don't use it from Python
            os.close(fh)
            if force_use_ffmpeg:
                raise AudioProcessingException(
                )  # Go to directly to ffmpeg conversion
            if not audioprocessing.convert_to_pcm(sound_path, tmp_wavefile):
                tmp_wavefile = sound_path
                self.log_info(
                    "no need to convert, this file is already PCM data")

        except IOError as e:
            # Could not create tmp file
            raise AudioProcessingException(
                "could not create tmp_wavefile file: %s" % e)
        except OSError as e:
            raise AudioProcessingException(
                "conversion to PCM failed, "
                "make sure that format conversion executables exist: %s" % e)
        except AudioProcessingException as e:
            # Conversion with format codecs has failed (or skipped using 'force_use_ffmpeg' argument)
            self.log_info(
                "conversion to PCM failed or skipped, now trying conversion with ffmpeg"
            )
            try:
                audioprocessing.convert_using_ffmpeg(sound_path,
                                                     tmp_wavefile,
                                                     mono_out=mono)
            except AudioProcessingException as e:
                raise AudioProcessingException("conversion to PCM failed: %s" %
                                               e)
            except OSError as e:
                raise AudioProcessingException(
                    "conversion to PCM failed, "
                    "make sure that ffmpeg executable exists: %s" % e)
        except Exception as e:
            raise AudioProcessingException(
                "unhandled exception while converting to PCM: %s" % e)

        self.log_info("PCM file path: " + tmp_wavefile)
        return tmp_wavefile
def process(sound):
    def failure(message, error=None):
        logging_message = "Failed to process audio file: %d\n" % sound.id + message
        sound.processing_log += "failed:" + message + "\n"
        
        if error:
            logging_message += "\n" + str(error)
            sound.processing_log += str(error) + "\n"

        sound.processing_state = "FA"
        sound.save()
        
    def success(message):
        sound.processing_log += message + "\n"
    
    def cleanup(files):
        success("cleaning up files after processing: " + ", ".join(files))
        for filename in files:
            try:
                os.unlink(filename)
            except:
                pass
    
    # only keep the last processing attempt
    sound.processing_log = "" 
    sound.processing_date = datetime.now()
    sound.save()

    if not os.path.exists(sound.original_path):
        failure("the file to be processed (%s) isn't there" % sound.original_path)
        return False
    success("found the file %s" % sound.original_path)
    
    sound.save()

    
    # convert to pcm
    to_cleanup = []
    tmp_wavefile = tempfile.mktemp(suffix=".wav", prefix=str(sound.id))
    
    try:
        if not audioprocessing.convert_to_pcm(sound.original_path, tmp_wavefile):
            tmp_wavefile = sound.original_path
            success("no need to convert, this file is already pcm data")
        else:
            to_cleanup.append(tmp_wavefile)
            success("converted to pcm: " + tmp_wavefile)
    except AudioProcessingException, e:
        failure("conversion to pcm has failed", e)
        return False
Esempio n. 3
0
def process(sound):

    def write_log(message):
        logger.info("[%d] %i: %s" % (os.getpid(),sound.id,message))
        sys.stdout.write(str(message)+'\n')
        sys.stdout.flush()

    def failure(message, error=None):
        sound.set_processing_ongoing_state("FI")
        sound.change_processing_state("FA", use_set_instead_of_save=True)
        logging_message = "Failed to process sound with id %s\n" % sound.id
        logging_message += "\tmessage: %s\n" % message
        if error:
            logging_message += "\terror: %s\n" % str(error)
        write_log(logging_message)

    def success(message):
        write_log(message)

    def cleanup(files):
        success("cleaning up files after processing: " + ", ".join(files))
        for filename in files:
            try:
                os.unlink(filename)
            except:
                pass

    # not saving the date of the processing attempt anymore
    sound.set_processing_ongoing_state("PR")

    new_path = sound.locations('path')
    # Is the file at its new location?
    if not os.path.exists(new_path):
        # Is the file at its old location?
        if not sound.original_path or not os.path.exists(sound.original_path):
            failure("The file to be processed can't be found at its FS1 nor at its FS2 location.")
            return False
        else:
            success("Found the file at its FS1 location: %s" % sound.original_path)
            if not sound.original_path.startswith('/mnt/freesound-data/'):
                failure("The file appears to be in a weird location and not in '/mnt/freesound-data/'!.")
                return False
            success("Copying file from %s to %s" % (sound.original_path, new_path))
            dest_dir = os.path.dirname(new_path)
            if not os.path.exists(dest_dir):
                try:
                    os.makedirs(dest_dir)
                except:
                    failure("Could not create destination directory %s" % dest_dir)
                    return False
            shutil.copy(sound.original_path, new_path)
            sound.set_original_path(new_path)
            success("Copied file from its FS1 to FS2 location.")
    else:
        success("Found the file at its FS2 location: %s" % new_path)
        if sound.original_path != new_path:
            sound.set_original_path(new_path)

    # convert to pcm
    to_cleanup = []
    try:
        tmp_wavefile = tempfile.mktemp(suffix=".wav", prefix=str(sound.id))
    except IOError as e:
        # Could not create tmp file
        failure("could not create tmp file", e)

    try:
        if not audioprocessing.convert_to_pcm(sound.original_path, tmp_wavefile):
            tmp_wavefile = sound.original_path
            success("no need to convert, this file is already pcm data")
        else:
            to_cleanup.append(tmp_wavefile)
            success("converted to pcm: " + tmp_wavefile)
    except AudioProcessingException, e:
        failure("conversion to pcm has failed, trying ffmpeg", e)
        try:
            audioprocessing.convert_using_ffmpeg(sound.original_path, tmp_wavefile)
            to_cleanup.append(tmp_wavefile)
            success("converted to pcm: " + tmp_wavefile)
        except AudioProcessingException, e:
            failure("conversion to pcm with ffmpeg failed", e)
            return False
Esempio n. 4
0
def process(sound):
    def write_log(message):
        sys.stdout.write(str(message) + '\n')
        sys.stdout.flush()

    def failure(message, error=None):
        sound.set_processing_state("FA")
        logging_message = "Failed to process sound with id %s\n" % sound.id
        logging_message += "\tmessage: %s\n" % message
        if error:
            logging_message += "\terror: %s\n" + str(error)
        write_log(message)

    def success(message):
        write_log(message)

    def cleanup(files):
        success("cleaning up files after processing: " + ", ".join(files))
        for filename in files:
            try:
                os.unlink(filename)
            except:
                pass

    # not saving the date of the processing attempt anymore
    sound.set_processing_state("PR")

    new_path = sound.locations('path')
    # Is the file at its new location?
    if not os.path.exists(new_path):
        # Is the file at its old location?
        if not sound.original_path or not os.path.exists(sound.original_path):
            failure(
                "The file to be processed can't be found at its FS1 nor at its FS2 location."
            )
            return False
        else:
            success("Found the file at its FS1 location: %s" %
                    sound.original_path)
            if not sound.original_path.startswith('/mnt/freesound-data/'):
                failure(
                    "The file appears to be in a weird location and not in '/mnt/freesound-data/'!."
                )
                return False
            success("Copying file from %s to %s" %
                    (sound.original_path, new_path))
            dest_dir = os.path.dirname(new_path)
            if not os.path.exists(dest_dir):
                try:
                    os.makedirs(dest_dir)
                except:
                    failure("Could not create destination directory %s" %
                            dest_dir)
                    return False
            shutil.copy(sound.original_path, new_path)
            sound.set_original_path(new_path)
            success("Copied file from its FS1 to FS2 location.")
    else:
        success("Found the file at its FS2 location: %s" % new_path)
        if sound.original_path != new_path:
            sound.set_original_path(new_path)

    # convert to pcm
    to_cleanup = []
    tmp_wavefile = tempfile.mktemp(suffix=".wav", prefix=str(sound.id))

    try:
        if not audioprocessing.convert_to_pcm(sound.original_path,
                                              tmp_wavefile):
            tmp_wavefile = sound.original_path
            success("no need to convert, this file is already pcm data")
        else:
            to_cleanup.append(tmp_wavefile)
            success("converted to pcm: " + tmp_wavefile)
    except AudioProcessingException, e:
        failure("conversion to pcm has failed, trying ffmpeg", e)
        try:
            audioprocessing.convert_using_ffmpeg(sound.original_path,
                                                 tmp_wavefile)
            to_cleanup.append(tmp_wavefile)
            success("converted to pcm: " + tmp_wavefile)
        except AudioProcessingException, e:
            failure("conversion to pcm with ffmpeg failed", e)
            return False
Esempio n. 5
0
def process(sound):
    def write_log(message):
        logger.info("[%d] %i: %s" % (os.getpid(), sound.id, message))
        sys.stdout.write(str(message) + '\n')
        sys.stdout.flush()

    def failure(message, error=None):
        sound.set_processing_ongoing_state("FI")
        sound.change_processing_state("FA", use_set_instead_of_save=True)
        logging_message = "Failed to process sound with id %s\n" % sound.id
        logging_message += "\tmessage: %s\n" % message
        if error:
            logging_message += "\terror: %s\n" % str(error)
        write_log(logging_message)

    def success(message):
        write_log(message)

    def cleanup(files):
        success("cleaning up files after processing: " + ", ".join(files))
        for filename in files:
            try:
                os.unlink(filename)
            except:
                pass

    # not saving the date of the processing attempt anymore
    sound.set_processing_ongoing_state("PR")

    new_path = sound.locations('path')
    # Is the file at its new location?
    if not os.path.exists(new_path):
        # Is the file at its old location?
        if not sound.original_path or not os.path.exists(sound.original_path):
            failure(
                "The file to be processed can't be found at its FS1 nor at its FS2 location."
            )
            return False
        else:
            success("Found the file at its FS1 location: %s" %
                    sound.original_path)
            if not sound.original_path.startswith('/mnt/freesound-data/'):
                failure(
                    "The file appears to be in a weird location and not in '/mnt/freesound-data/'!."
                )
                return False
            success("Copying file from %s to %s" %
                    (sound.original_path, new_path))
            dest_dir = os.path.dirname(new_path)
            if not os.path.exists(dest_dir):
                try:
                    os.makedirs(dest_dir)
                except:
                    failure("Could not create destination directory %s" %
                            dest_dir)
                    return False
            shutil.copy(sound.original_path, new_path)
            sound.set_original_path(new_path)
            success("Copied file from its FS1 to FS2 location.")
    else:
        success("Found the file at its FS2 location: %s" % new_path)
        if sound.original_path != new_path:
            sound.set_original_path(new_path)

    # convert to pcm
    to_cleanup = []
    try:
        tmp_wavefile = tempfile.mktemp(suffix=".wav", prefix=str(sound.id))
    except IOError as e:
        # Could not create tmp file
        failure("could not create tmp file", e)

    try:
        if not audioprocessing.convert_to_pcm(sound.original_path,
                                              tmp_wavefile):
            tmp_wavefile = sound.original_path
            success("no need to convert, this file is already pcm data")
        else:
            to_cleanup.append(tmp_wavefile)
            success("converted to pcm: " + tmp_wavefile)
    except AudioProcessingException as e:
        failure("conversion to pcm has failed, trying ffmpeg", e)
        try:
            audioprocessing.convert_using_ffmpeg(sound.original_path,
                                                 tmp_wavefile)
            to_cleanup.append(tmp_wavefile)
            success("converted to pcm: " + tmp_wavefile)
        except AudioProcessingException as e:
            failure("conversion to pcm with ffmpeg failed", e)
            return False
    except Exception as e:
        failure("unhandled exception", e)
        cleanup(to_cleanup)
        return False

    tmp_wavefile2 = tempfile.mktemp(suffix=".wav", prefix=str(sound.id))

    try:
        info = audioprocessing.stereofy_and_find_info(settings.STEREOFY_PATH,
                                                      tmp_wavefile,
                                                      tmp_wavefile2)
        to_cleanup.append(tmp_wavefile2)
    except AudioProcessingException as e:
        failure("stereofy has failed, trying ffmpeg first", e)
        try:
            audioprocessing.convert_using_ffmpeg(sound.original_path,
                                                 tmp_wavefile)
            info = audioprocessing.stereofy_and_find_info(
                settings.STEREOFY_PATH, tmp_wavefile, tmp_wavefile2)
            #if tmp_wavefile not in to_cleanup: to_cleanup.append(tmp_wavefile)
            to_cleanup.append(tmp_wavefile2)
        except AudioProcessingException as e:
            failure("ffmpeg + stereofy failed", e)
            cleanup(to_cleanup)
            return False
    except Exception as e:
        failure("unhandled exception", e)
        cleanup(to_cleanup)
        return False

    success("got sound info and stereofied: " + tmp_wavefile2)
    if sound.type in ["mp3", "ogg", "m4a"]:
        info['bitdepth'] = 0  # mp3 and ogg don't have bitdepth

    try:
        sound.set_audio_info_fields(info)
    except Exception as e:  # Could not catch a more specific exception
        failure("failed writting audio info fields to db", e)

    for mp3_path, quality in [(sound.locations("preview.LQ.mp3.path"), 70),
                              (sound.locations("preview.HQ.mp3.path"), 192)]:
        # create preview
        try:
            os.makedirs(os.path.dirname(mp3_path))
        except OSError:
            pass

        try:
            audioprocessing.convert_to_mp3(tmp_wavefile2, mp3_path, quality)
        except AudioProcessingException as e:
            cleanup(to_cleanup)
            failure("conversion to mp3 (preview) has failed", e)
            return False
        except Exception as e:
            failure("unhandled exception", e)
            cleanup(to_cleanup)
            return False
        success("created mp3: " + mp3_path)

    for ogg_path, quality in [(sound.locations("preview.LQ.ogg.path"), 1),
                              (sound.locations("preview.HQ.ogg.path"), 6)]:
        # create preview
        try:
            os.makedirs(os.path.dirname(ogg_path))
        except OSError:
            pass

        try:
            audioprocessing.convert_to_ogg(tmp_wavefile2, ogg_path, quality)
        except AudioProcessingException as e:
            cleanup(to_cleanup)
            failure("conversion to ogg (preview) has failed", e)
            return False
        except Exception as e:
            failure("unhandled exception", e)
            cleanup(to_cleanup)
            return False
        success("created ogg: " + ogg_path)

    # create waveform images M
    waveform_path_m = sound.locations("display.wave.M.path")
    spectral_path_m = sound.locations("display.spectral.M.path")

    try:
        os.makedirs(os.path.dirname(waveform_path_m))
    except OSError:
        pass

    try:
        audioprocessing.create_wave_images(tmp_wavefile2, waveform_path_m,
                                           spectral_path_m, 120, 71, 2048)
    except AudioProcessingException as e:
        cleanup(to_cleanup)
        failure("creation of images (M) has failed", e)
        return False
    except Exception as e:
        failure("unhandled exception", e)
        cleanup(to_cleanup)
        return False
    success("created previews, medium")

    # create waveform images L
    waveform_path_l = sound.locations("display.wave.L.path")
    spectral_path_l = sound.locations("display.spectral.L.path")
    try:
        audioprocessing.create_wave_images(tmp_wavefile2, waveform_path_l,
                                           spectral_path_l, 900, 201, 2048)
    except AudioProcessingException as e:
        cleanup(to_cleanup)
        failure("creation of images (L) has failed", e)
        return False
    except Exception as e:
        failure("unhandled exception", e)
        cleanup(to_cleanup)
        return False
    success("created previews, large")

    cleanup(to_cleanup)
    sound.set_processing_ongoing_state("FI")
    sound.change_processing_state("OK", use_set_instead_of_save=True)

    # Copy previews and display files to mirror locations
    copy_previews_to_mirror_locations(sound)
    copy_displays_to_mirror_locations(sound)

    return True
def process(sound, skip_previews=False, skip_displays=False):
    def write_log(message):
        sys.stdout.write(str(message) + '\n')
        sys.stdout.flush()
        logger.info("[%d] %i: %s" % (os.getpid(), sound.id, message))

    def create_directory(path):
        try:
            os.makedirs(path)
        except OSError as exc:
            if exc.errno == errno.EEXIST and os.path.isdir(path):
                # Directory already exists
                pass
            else:
                # Directory could not be created, raise exception
                raise

    def cleanup(files):
        success("cleaning up processing files: " + ", ".join(files))
        for filename in files:
            try:
                os.unlink(filename)
            except:
                pass

    def failure(message, error=None):
        sound.set_processing_ongoing_state("FI")
        sound.change_processing_state("FA", use_set_instead_of_save=True)
        logging_message = "ERROR: Failed to process sound with id %s\n" % sound.id
        logging_message += "\tmessage: %s\n" % message
        if error:
            logging_message += "\terror: %s" % str(error)
        write_log(logging_message)
        cleanup(to_cleanup)

    def success(message):
        write_log('- ' + message)

    to_cleanup = [
    ]  # This will hold a list of files to cleanup after processing

    # Change ongoing processing state to "processing" in Sound model
    sound.set_processing_ongoing_state("PR")

    # Get the path of the original sound
    sound_path = sound.locations('path')
    if settings.USE_PREVIEWS_WHEN_ORIGINAL_FILES_MISSING and not os.path.exists(
            sound_path):
        sound_path = sound.locations('preview.LQ.mp3.path')
    if not os.path.exists(sound_path):
        failure("can't process sound as file does not exist")
        return False
    success("file to process found in " + sound_path)

    # Convert to PCM and save PCM version in `tmp_wavefile`
    try:
        tmp_wavefile = tempfile.mktemp(suffix=".wav", prefix=str(sound.id))
        if not audioprocessing.convert_to_pcm(sound_path, tmp_wavefile):
            tmp_wavefile = sound_path
            success("no need to convert, this file is already PCM data")
        else:
            to_cleanup.append(tmp_wavefile)
            success("converted to pcm: " + tmp_wavefile)
    except IOError as e:
        # Could not create tmp file
        failure("could not create tmp_wavefile file", e)
        return False
    except AudioProcessingException as e:
        try:
            audioprocessing.convert_using_ffmpeg(sound_path, tmp_wavefile)
            to_cleanup.append(tmp_wavefile)
            success("converted to PCM: " + tmp_wavefile)
        except AudioProcessingException as e:
            failure("conversion to PCM failed", e)
            return False
    except Exception as e:
        failure("unhandled exception while converting to PCM", e)
        return False

    # Now get info about the file, stereofy it and save new stereofied PCM version in `tmp_wavefile2`
    try:
        tmp_wavefile2 = tempfile.mktemp(suffix=".wav", prefix=str(sound.id))
        to_cleanup.append(tmp_wavefile2)
        info = audioprocessing.stereofy_and_find_info(settings.STEREOFY_PATH,
                                                      tmp_wavefile,
                                                      tmp_wavefile2)
        if sound.type in ["mp3", "ogg", "m4a"]:
            info['bitdepth'] = 0  # mp3 and ogg don't have bitdepth
        success("got sound info and stereofied: " + tmp_wavefile2)
    except IOError as e:
        # Could not create tmp file
        failure("could not create tmp_wavefile2 file", e)
        return False
    except AudioProcessingException as e:
        failure("stereofy has failed", e)
        return False
    except Exception as e:
        failure("unhandled exception while getting info and running stereofy",
                e)
        return False

    # Fill audio information fields in Sound object
    try:
        sound.set_audio_info_fields(info)
    except Exception as e:  # Could not catch a more specific exception
        failure("failed writting audio info fields to db", e)
        return False

    # Generate MP3 and OGG previews
    if not skip_previews:

        # Create directory to store previews (if it does not exist)
        # Same directory is used for all MP3 and OGG previews of a given sound so we only need to run this once
        try:
            create_directory(
                os.path.dirname(sound.locations("preview.LQ.mp3.path")))
        except OSError:
            failure("could not create directory for previews")
            return False

        # Generate MP3 previews
        for mp3_path, quality in [(sound.locations("preview.LQ.mp3.path"), 70),
                                  (sound.locations("preview.HQ.mp3.path"), 192)
                                  ]:
            try:
                audioprocessing.convert_to_mp3(tmp_wavefile2, mp3_path,
                                               quality)
            except AudioProcessingException as e:
                failure("conversion to mp3 (preview) has failed", e)
                return False
            except Exception as e:
                failure("unhandled exception generating MP3 previews", e)
                return False
            success("created mp3: " + mp3_path)

        # Generate OGG previews
        for ogg_path, quality in [(sound.locations("preview.LQ.ogg.path"), 1),
                                  (sound.locations("preview.HQ.ogg.path"), 6)]:
            try:
                audioprocessing.convert_to_ogg(tmp_wavefile2, ogg_path,
                                               quality)
            except AudioProcessingException as e:
                failure("conversion to ogg (preview) has failed", e)
                return False
            except Exception as e:
                failure("unhandled exception generating OGG previews", e)
                return False
            success("created ogg: " + ogg_path)

    # Generate display images for different sizes and colour scheme front-ends
    if not skip_displays:

        # Create directory to store display images (if it does not exist)
        # Same directory is used for all displays of a given sound so we only need to run this once
        try:
            create_directory(
                os.path.dirname(sound.locations("display.wave.M.path")))
        except OSError:
            failure("could not create directory for displays")
            return False

        # Generate display images, M and L sizes for NG and BW front-ends
        for width, height, color_scheme, waveform_path, spectral_path in [
            (120, 71, color_schemes.FREESOUND2_COLOR_SCHEME,
             sound.locations("display.wave.M.path"),
             sound.locations("display.spectral.M.path")),
            (500, 201, color_schemes.BEASTWHOOSH_COLOR_SCHEME,
             sound.locations("display.wave_bw.M.path"),
             sound.locations("display.spectral_bw.M.path")),
            (900, 201, color_schemes.FREESOUND2_COLOR_SCHEME,
             sound.locations("display.wave.L.path"),
             sound.locations("display.spectral.L.path")),
            (1500, 401, color_schemes.BEASTWHOOSH_COLOR_SCHEME,
             sound.locations("display.wave_bw.L.path"),
             sound.locations("display.spectral_bw.L.path"))
        ]:
            try:
                fft_size = 2048
                audioprocessing.create_wave_images(tmp_wavefile2,
                                                   waveform_path,
                                                   spectral_path,
                                                   width,
                                                   height,
                                                   fft_size,
                                                   color_scheme=color_scheme)
                success("created wave and spectrogram images: %s, %s" %
                        (waveform_path, spectral_path))
            except AudioProcessingException as e:
                failure("creation of display images has failed", e)
                return False
            except Exception as e:
                failure("unhandled exception while generating displays", e)
                return False

    # Clean up temp files
    cleanup(to_cleanup)

    # Change processing state and processing ongoing state in Sound model
    sound.set_processing_ongoing_state("FI")
    sound.change_processing_state("OK", use_set_instead_of_save=True)

    # Copy previews and display files to mirror locations
    copy_previews_to_mirror_locations(sound)
    copy_displays_to_mirror_locations(sound)

    return True