Странные шумы и отклонения при записи аудиоданных из libspotify в файл

В настоящее время мы внедряем Libspotify в 64-битной системе win 7. Кажется, все работает нормально, кроме воспроизведения. Мы получаем данные из функции обратного вызова, но даже при использовании аудиичности сохраненного аудио-файла, он полон аномалий. Поэтому для дальнейшего исследования мы взяли образец win32 (spshell) и изменили его, чтобы сохранить музыкальные данные в файл. Та же проблема, определенно музыка с этими галочками. Я уверен, что здесь есть что-то простое, что мне не хватает, но я не знаю, в чем может быть проблема. Любая помощь будет полезна, поскольку наш проект стоит на месте, пока мы не сможем решить эту проблему.

Сохраненное аудио можно посмотреть здесь http://uploader.crestron.com/download.php?file=8001d80992480280dba365752aeaca81

Ниже приведены изменения кода, которые я сделал для сохранения файла (только для тестирования)

static FILE *pFile;
int numBytesToWrite=0;
CRITICAL_SECTION m_cs;

int SP_CALLCONV music_delivery(sp_session *s, const sp_audioformat *fmt, const void *frames, int num_frames)
{
    if ( num_frames == 0 )
        return;
    EnterCriticalSection(&m_cs);
    numBytesToWrite = ( num_frames ) * fmt->channels * sizeof(short);
    if (numBytesToWrite > 0 )
        fwrite(frames, sizeof(short), numBytesToWrite, pFile);
    LeaveCriticalSection(&m_cs);
    return num_frames;
}
static void playtrack_test(void)
{


    sp_error err;
    InitializeCriticalSection(&m_cs);
    pFile = fopen ("C:\\zzzspotify.pcm","wb");
    test_start(&playtrack);
    if((err = sp_session_player_load(g_session, stream_track)) != SP_ERROR_OK) {
        test_report(&playtrack, "Unable to load track: %s",  sp_error_message(err));
        return;
    }

    info_report("Streaming '%s' by '%s' this will take a while", sp_track_name(stream_track),
            sp_artist_name(sp_track_artist(stream_track, 0)));
    sp_session_player_play(g_session, 1);
}

void SP_CALLCONV play_token_lost(sp_session *s)
{
    fclose(pFile);
    DeleteCriticalSection(&m_cs);
    stream_track_end = 2;
    notify_main_thread(g_session);
    info_report("Playtoken lost");
}
static int check_streaming_done(void)
{
    if(stream_track_end == 2)
        test_report(&playtrack, "Playtoken lost");
    else if(stream_track_end == 1)
        test_ok(&playtrack);
    else
        return 0;
    fclose(pFile);
    stream_track_end = 0;
    return 1;
}

1 ответ

Решение

Похоже, что это проблема:

fwrite(frames, sizeof(short), numBytesToWrite, pFile);

fwrite В документации говорится, что второй аргумент - это "размер в байтах каждого записываемого элемента", а третий - это "количество элементов, каждый из которых имеет размер в байтах размера ".

То, как вы звоните frwriteскажу это написать numBytesToWrite * sizeof(short) байты, которые будут выполняться сразу после конца данного буфера. Я на самом деле удивлен, что он не падает!

Я бы предложил изменить ваш fwrite позвонить что-то вроде:

fwrite(frames, sizeof(char), numBytesToWrite, pFile);

или же:

int numSamplesToWrite = num_frames * fmt->channels;
fwrite(frames, sizeof(short), numSamplesToWrite, pFile);

Редактировать:

Посмотрев на ваше аудио подробно, я более убежден, что это так. Песня, кажется, воспроизводится с половинной скоростью (т.е. в 2 раза больше данных записывается), а артефакты выглядят как переполнение буфера в случайной памяти.

Другие вопросы по тегам