예제 #1
0
    def handle(self, dbs, *args, **options):
        # Correct false wav info
        for af in AudioFile.objects.all():
            wav_file_path = wav_path(af, 'wav')
            fs, length = get_wav_info(wav_file_path)
            if fs != af.fs or length != af.length:
                print(
                    'Correct file {}, originally length={} fs={}, now length={}, fs={}'
                    .format(af.name, af.length, af.fs, length, fs))
                af.fs = fs
                af.length = length
                af.save()

        conns = None
        try:
            conns = get_dbconf(dbs)
            for pop in conns:
                conn = conns[pop]
                cur = conn.cursor()
                bitrate = 16
                song_cur = conn.cursor(
                    cursor_factory=psycopg2.extras.RealDictCursor)

                song_cur.execute(
                    'select w.framesize, w.stereo, w.samplerate, w.ssizeinbits, w.songid, s.name '
                    'from wavs w join songdata s on w.songid=s.id where w.ssizeinbits={}'
                    .format(bitrate))

                songs = song_cur.fetchall()
                for song in songs:
                    song_name = song['name']
                    # Import WAV data and save as WAV and MP3 files
                    wav_file_path = '/tmp/{}'.format(song_name)
                    mp3_file_path = '/tmp/{}.mp3'.format(song_name)
                    fs, length = import_pcm(song, cur, song_name,
                                            wav_file_path, mp3_file_path)

                    fs1, length1 = get_wav_info(wav_file_path)

                    if fs != fs1 or length != length1:
                        print('-------SHIT--------')

                    print(
                        'Song {} length = {} fs = {} time = {}, length1 = {} fs1 = {} time1 = {}'
                        .format(song_name, length, fs, length / fs, length1,
                                fs1, length1 / fs1))
        finally:
            for dbconf in conns:
                conn = conns[dbconf]
                if conn is not None:
                    conn.close()
예제 #2
0
def extract_segment_feature_for_audio_file(wav_file_path, segs_info, feature,
                                           **kwargs):
    fs, length = get_wav_info(wav_file_path)

    args = dict(wav_file_path=wav_file_path,
                fs=fs,
                start=0,
                end=None,
                center=False,
                order=44)

    for v, k in kwargs.items():
        args[v] = k

    extractor = feature_extractors[feature.name]
    tids = []
    fvals = []

    for tid, beg, end, nfft, noverlap, lpf, hpf in segs_info:
        args['start'] = beg
        args['end'] = end
        args['nfft'] = nfft
        args['noverlap'] = noverlap
        args['lpf'] = lpf
        args['hpf'] = hpf
        args['win_length'] = nfft

        feature_value = extractor(args)
        tids.append(tid)
        fvals.append(feature_value)

    return tids, fvals
예제 #3
0
파일: model_utils.py 프로젝트: jren2019/koe
def extract_spectrogram(audio_file, segs_info):
    """
    Extract raw sepectrograms for all segments (Not the masked spectrogram from Luscinia) of an audio file
    :param audio_file:
    :return:
    """
    filepath = wav_path(audio_file)

    fs, duration = get_wav_info(filepath)
    if not os.path.isfile(filepath):
        raise CustomAssertionError("File {} not found".format(audio_file.name))

    for tid, start, end in segs_info:
        seg_spect_path = get_abs_spect_path(tid)
        ensure_parent_folder_exists(seg_spect_path)

        sig = read_segment(filepath,
                           beg_ms=start,
                           end_ms=end,
                           mono=True,
                           normalised=True,
                           return_fs=False,
                           retype=True,
                           winlen=window_size)
        _, _, s = signal.stft(sig,
                              fs=fs,
                              window=window,
                              noverlap=noverlap,
                              nfft=window_size,
                              return_onesided=True)
        spect = np.abs(s * scale)

        height, width = np.shape(spect)
        spect = np.flipud(spect)

        spect = np.log10(spect)
        spect = ((spect - global_min_spect_pixel) / interval64)
        spect[np.isinf(spect)] = 0
        spect = spect.astype(np.int)

        spect = spect.reshape((width * height, ), order='C')
        spect[spect >= 64] = 63
        spect_rgb = np.empty((height, width, 3), dtype=np.uint8)
        spect_rgb[:, :, 0] = cm_red[spect].reshape((height, width)) * 255
        spect_rgb[:, :, 1] = cm_green[spect].reshape((height, width)) * 255
        spect_rgb[:, :, 2] = cm_blue[spect].reshape((height, width)) * 255

        # roi_start = int(start / duration_ms * width)
        # roi_end = int(np.ceil(end / duration_ms * width))

        # seg_spect_rgb = file_spect_rgb[:, roi_start:roi_end, :]
        seg_spect_img = Image.fromarray(spect_rgb)

        seg_spect_img.save(seg_spect_path, format='PNG')
        celerylogger.info('spectrogram {} created'.format(seg_spect_path))
예제 #4
0
 def _test_single_file(self, filepath):
     fs, length = wavfile.get_wav_info(filepath)
     try:
         with contextlib.closing(wave.open(filepath, 'r')) as f:
             correct_length = f.getnframes()
             correct_fs = f.getframerate()
         self.assertEqual(fs, correct_fs)
         self.assertEqual(length, correct_length)
     except wave.Error as e:
         warning(
             'Library wave is unable to read file {}. Error is: {}'.format(
                 filepath, e))
예제 #5
0
파일: utils.py 프로젝트: jren2019/koe
def wav_2_mono(file, **kwargs):
    """
    Read a wav file and return fs and first channel's data stream.
    The data is normalised to be equivalent to Matlab's `audioread(...)` function
    :param file:
    :return: fs and signal
    """
    data = wavfile.read_segment(file, **kwargs)
    if len(np.shape(data)) > 1:
        data = data[:, 0]

    fs, _ = get_wav_info(file)
    return fs, data
예제 #6
0
def add_noc_to_audio_files(apps, schema_editor):
    """
    """
    db_alias = schema_editor.connection.alias
    audio_file_model = apps.get_model('koe', 'AudioFile')

    original_audio_files = audio_file_model.objects.using(db_alias).filter(
        original=None)
    inoriginal_audio_files = audio_file_model.objects.using(db_alias).exclude(
        original=None)

    afid_to_noc = {}

    slashed_url = os.path.join(settings.MEDIA_URL, 'audio/wav/{}', '{}.wav')
    unslashed_url = slashed_url[1:]
    wav_path_template = os.path.join(settings.BASE_DIR, unslashed_url)

    sys.stdout.write('\n')
    sys.stdout.write(
        '\tAdding number of channels to {} original AudioFiles...'.format(
            len(original_audio_files)))

    for audio_file in original_audio_files:
        database_id = audio_file.database.id
        file_name = audio_file.name
        file_path = wav_path_template.format(database_id, file_name)

        if os.path.isfile(file_path):
            _, _, noc = get_wav_info(file_path, return_noc=True)
        else:
            noc = 1
        afid_to_noc[audio_file.id] = noc

        audio_file.noc = noc

    bulk_update(original_audio_files, update_fields=['noc'], batch_size=10000)
    sys.stdout.write('Done\n')
    sys.stdout.write(
        '\tAdding number of channels to {} dependent AudioFiles...'.format(
            len(inoriginal_audio_files)))

    for audio_file in inoriginal_audio_files:
        original_afid = audio_file.original.id
        audio_file.noc = afid_to_noc[original_afid]

    bulk_update(inoriginal_audio_files,
                update_fields=['noc'],
                batch_size=10000)
예제 #7
0
def import_pcm(song, cur, audio_file, wav_file_path=None, compressed_url=None):
    if wav_file_path is None:
        wav_file_path = wav_path(audio_file)
    if compressed_url is None:
        compressed_url = audio_path(audio_file, settings.AUDIO_COMPRESSED_FORMAT)

    if not os.path.isfile(wav_file_path):
        # print('Importing {}'.format(song_name))
        song_id = song['songid']
        cur.execute('select wav from wavs where songid={};'.format(song_id))

        data = cur.fetchone()
        raw_pcm = str_to_bytes(data[0])

        nchannels = song['stereo']
        bitrate = int(song['ssizeinbits'])
        fs = int(song['samplerate'])

        byte_per_frame = int(bitrate / 8)
        nframes_all_channel = int(len(raw_pcm) / byte_per_frame)
        nframes_per_channel = int(nframes_all_channel / nchannels)
        length = nframes_per_channel
        ensure_parent_folder_exists(wav_file_path)

        if bitrate == 24:
            array1 = np.frombuffer(raw_pcm, dtype=np.ubyte)
            array2 = array1.reshape((nframes_per_channel, nchannels, byte_per_frame)).astype(np.uint8)
            wf.write_24b(wav_file_path, fs, array2)
        else:
            data = array.array('i', raw_pcm)
            sound = pydub.AudioSegment(data=data, sample_width=byte_per_frame, frame_rate=fs, channels=nchannels)
            sound.export(wav_file_path, 'wav')
    else:
        fs, length = get_wav_info(wav_file_path)

    if not os.path.isfile(compressed_url):
        ensure_parent_folder_exists(compressed_url)
        sound = pydub.AudioSegment.from_wav(wav_file_path)
        sound.export(compressed_url, format=settings.AUDIO_COMPRESSED_FORMAT)

    return fs, length
예제 #8
0
파일: audio.py 프로젝트: jren2019/koe
def _import_and_convert_audio_file(database,
                                   file,
                                   max_fs,
                                   real_fs=None,
                                   audio_file=None,
                                   track=None,
                                   start=None,
                                   end=None):

    file_already_exists = False
    if isinstance(file, BufferedWriter):
        file_already_exists = True
        name_ext = os.path.basename(file.name)
    else:
        name_ext = file.name

    if name_ext.lower().endswith('.wav'):
        name_no_ext = name_ext[:-4]
    else:
        name_no_ext = name_ext

    # Need a unique name (database-wide) for new file
    if audio_file is None:
        is_unique = not AudioFile.objects.filter(database=database,
                                                 name=name_no_ext).exists()
        if not is_unique:
            raise CustomAssertionError(
                'File {} already exists'.format(name_no_ext))
    elif audio_file.name != name_no_ext:
        raise CustomAssertionError(
            'Impossible! File name in your table and in the database don\'t match'
        )

    wav_name = data_path('audio/wav/{}'.format(database.id),
                         '{}.wav'.format(name_no_ext))
    name_compressed = data_path(
        'audio/{}/{}'.format(settings.AUDIO_COMPRESSED_FORMAT, database.id),
        '{}.{}'.format(name_no_ext, settings.AUDIO_COMPRESSED_FORMAT))

    fake_wav_name = wav_name + '.bak'

    if not file_already_exists:
        with open(wav_name, 'wb') as wav_file:
            wav_file.write(file.read())

    _fs, length, noc = get_wav_info(wav_name, return_noc=True)

    # If real_fs is provided, it is absolute -- otherwise it is what we can really read from the file
    if real_fs is None:
        real_fs = _fs

    fake_fs = None
    # If real_fs is not what we read from the file, then the file is fake, and we must restore the original file
    # to do that we rename the wav file that we just stored (which is fake) to .bak, then change the sample rate
    # back to the original and store the original file as .wav
    if real_fs != _fs:
        os.rename(wav_name, fake_wav_name)
        change_fs_without_resampling(fake_wav_name, real_fs, wav_name)
        audio = pydub.AudioSegment.from_file(fake_wav_name)
        os.remove(fake_wav_name)

    # Otherwise, if real_fs is more than max_fs, we must create a fake file for the sake of converting to mp3:
    elif real_fs > max_fs:
        fake_fs = max_fs
        change_fs_without_resampling(wav_name, fake_fs, fake_wav_name)
        audio = pydub.AudioSegment.from_file(fake_wav_name)
        os.remove(fake_wav_name)
    # Otherwise the file is ordinary - no need to fake it
    else:
        audio = pydub.AudioSegment.from_file(wav_name)

    ensure_parent_folder_exists(name_compressed)
    audio.export(name_compressed, format=settings.AUDIO_COMPRESSED_FORMAT)

    if audio_file is None:
        if track is None:
            track = AudioTrack.objects.get_or_create(name='TBD')[0]
        individual = Individual.objects.get_or_create(name='TBD')[0]
        audio_file = AudioFile(name=name_no_ext,
                               length=length,
                               fs=real_fs,
                               database=database,
                               track=track,
                               start=start,
                               end=end,
                               fake_fs=fake_fs,
                               added=timezone.now(),
                               noc=noc,
                               individual=individual)
        audio_file.save()
        if track.name == 'TBD':
            track.name = str(audio_file.id)
            track.save()
        individual.name = str(audio_file.id)
        individual.save()
    else:
        audio_file.start = start
        audio_file.end = end
        audio_file.length = length
        audio_file.save()

    return audio_file