Что не так с моим кодом?Я получаю «Ошибка шины» - PullRequest
1 голос
/ 10 июля 2011

Я пытаюсь прочитать файл с необработанным аудио и закодировать его, используя FLAC . Когда я запускаю программу, я получаю «Ошибка шины». Что может быть не так?
Я компилирую на OS X 10.6.8, используя следующую строку:

gcc nsFlacEncoder.c -I/opt/local/include -lflac -m32 -o flac_enc

#include "FLAC/stream_encoder.h"
#define READSIZE 40000
char buffer[READSIZE];
FLAC__int32 pcm[READSIZE/2];

FLAC__StreamEncoderWriteStatus write_callback(const FLAC__StreamEncoder *encoder, const  FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame, void *client_data)
{
    FILE * fp;
    fp = fopen("rec.flac","rw");
    fwrite(buffer, 1, bytes, fp);
    fclose(fp);
    return 0;
}

int rawToFlac()
{
    FLAC__bool ok = true;
    FLAC__StreamEncoder *encoder = 0;
    FLAC__StreamEncoderInitStatus init_status;
    unsigned sample_rate = 16000;
    unsigned channels = 1;
    unsigned bps = 16;

    if((encoder=FLAC__stream_encoder_new()) == NULL){
        printf("Error!");
        return 1;
    }

    ok &= FLAC__stream_encoder_set_verify(encoder, true);
    ok &= FLAC__stream_encoder_set_compression_level(encoder, 5);
    ok &= FLAC__stream_encoder_set_channels(encoder, channels);
    ok &= FLAC__stream_encoder_set_bits_per_sample(encoder, bps);
    ok &= FLAC__stream_encoder_set_sample_rate(encoder, sample_rate);
    ok &= FLAC__stream_encoder_set_total_samples_estimate(encoder, READSIZE);

    if(ok){
        init_status = FLAC__stream_encoder_init_stream(encoder, &write_callback, NULL, NULL, NULL, /*client_data=*/NULL);
        if(init_status != FLAC__STREAM_ENCODER_INIT_STATUS_OK){
            printf("Encoder not initiated");
            return 1;
        }
    }

    if(ok){
        while(ok)
        {       
            /* convert the packed little-endian 16-bit PCM samples from WAVE into an interleaved FLAC__int32 buffer for libFLAC */
            size_t i;
            for(i = 0; i < 20000; i++) {
                /* inefficient but simple and works on big- or little-endian machines */
                pcm[i] = (FLAC__int32)(((FLAC__int16)(FLAC__int8)buffer[2*i+1] << 8) | (FLAC__int16)buffer[2*i]);
            }
            /* feed samples to encoder */
            ok = FLAC__stream_encoder_process_interleaved(encoder, pcm, 20000);
        }
    }

    ok &= FLAC__stream_encoder_finish(encoder);
    printf("Finished.");

    FLAC__stream_encoder_delete(encoder);   
    return 0;
}

int main()
{

    FILE *file;
    file = fopen("recording","rb");
    fread(buffer,2, 20000, file);
    rawToFlac();
    fclose(file);
    return 0;
}

Запуск gdb flac_enc дает мне это:

warning: Could not find object file "/Users/benski/Desktop/flac-1.2.1/src/libFLAC/.libs/bitmath.o" - no debug information available for "bitmath.c".
warning: Could not find object file "/Users/benski/Desktop/flac-1.2.1/src/libFLAC/.libs/bitreader.o" - no debug information available for "bitreader.c".
warning: Could not find object file "/Users/benski/Desktop/flac-1.2.1/src/libFLAC/.libs/bitwriter.o" - no debug information available for "bitwriter.c".
warning: Could not find object file "/Users/benski/Desktop/flac-1.2.1/src/libFLAC/.libs/cpu.o" - no debug information available for "cpu.c".
warning: Could not find object file "/Users/benski/Desktop/flac-1.2.1/src/libFLAC/.libs/crc.o" - no debug information available for "crc.c".
warning: Could not find object file "/Users/benski/Desktop/flac-1.2.1/src/libFLAC/.libs/fixed.o" - no debug information available for "fixed.c".
warning: Could not find object file "/Users/benski/Desktop/flac-1.2.1/src/libFLAC/.libs/format.o" - no debug information available for "format.c".
warning: Could not find object file "/Users/benski/Desktop/flac-1.2.1/src/libFLAC/.libs/lpc.o" - no debug information available for "lpc.c".
warning: Could not find object file "/Users/benski/Desktop/flac-1.2.1/src/libFLAC/.libs/md5.o" - no debug information available for "md5.c".
warning: Could not find object file "/Users/benski/Desktop/flac-1.2.1/src/libFLAC/.libs/memory.o" - no debug information available for "memory.c".
warning: Could not find object file "/Users/benski/Desktop/flac-1.2.1/src/libFLAC/.libs/metadata_iterators.o" - no debug information available for "metadata_iterators.c".
warning: Could not find object file "/Users/benski/Desktop/flac-1.2.1/src/libFLAC/.libs/metadata_object.o" - no debug information available for "metadata_object.c".
warning: Could not find object file "/Users/benski/Desktop/flac-1.2.1/src/libFLAC/.libs/stream_decoder.o" - no debug information available for "stream_decoder.c".
warning: Could not find object file "/Users/benski/Desktop/flac-1.2.1/src/libFLAC/.libs/stream_encoder.o" - no debug information available for "stream_encoder.c".
warning: Could not find object file "/Users/benski/Desktop/flac-1.2.1/src/libFLAC/.libs/stream_encoder_framing.o" - no debug information available for "stream_encoder_framing.c".
warning: Could not find object file "/Users/benski/Desktop/flac-1.2.1/src/libFLAC/.libs/window.o" - no debug information available for "window.c".
warning: Could not find object file "/Users/benski/Desktop/flac-1.2.1/src/libFLAC/.libs/ogg_decoder_aspect.o" - no debug information available for "ogg_decoder_aspect.c".
warning: Could not find object file "/Users/benski/Desktop/flac-1.2.1/src/libFLAC/.libs/ogg_encoder_aspect.o" - no debug information available for "ogg_encoder_aspect.c".
warning: Could not find object file "/Users/benski/Desktop/flac-1.2.1/src/libFLAC/.libs/ogg_helper.o" - no debug information available for "ogg_helper.c".
warning: Could not find object file "/Users/benski/Desktop/flac-1.2.1/src/libFLAC/.libs/ogg_mapping.o" - no debug information available for "ogg_mapping.c".

Это странно, поскольку в моей системе нет пользователя "benski". Но я уверен, что библиотеки FLAC установлены правильно, так как примеры программ работают отлично.

Ответы [ 3 ]

1 голос
/ 10 июля 2011

В main() вы не проверяете, что файл был успешно открыт.Проблема может заключаться в том, что вы используете нулевой указатель в операции fread().Точно так же в функции write_callback() ваш код показывает предположение о непобедимости.(Кроме того, если ваш обратный вызов вызывается более одного раза, второй вызов перезаписывает данные, полученные при первом вызове. Однако это другая проблема.)

Вы не проверяете, сколько 2-байтовыхединицы были прочитаны fread().Также вы не проверяете, сколько данных записывает fwrite() - было ли это успешно?

Вы должны иметь возможность использовать gdb или подобный отладчик, чтобы увидеть, где происходит ошибка.

Возможно, вы также сможете использовать valgrind, чтобы определить проблему.

Вам не нужны ни if, ни while in:

if (ok)
{
    while (ok)
    {
        ...
    }
}

Один циклдостаточно;оно будет выполнено ноль раз, если ok ложно в первом цикле.Если после цикла while и до конца if был оператор, то оба были бы необходимы.

В общем случае SIGBUS (ошибка шины) возникает на чипах RISC при попытке доступаобъект данных, который смещен.Не ясно, какая строка может быть причиной этой проблемы в этом коде.Несмотря на ранее высказанный комментарий о «нулевом указателе», это обычно заканчивается SIGSEGV (нарушение сегментации), чем SIGBUS.

0 голосов
/ 10 июля 2011

Дайте знать больше деталей, пока вы ожидаете, что некоторые указатели решат вашу проблему, например - какая платформа, компилятор, опции компилятора (включена ли какая-либо оптимизация и т. Д.).

AFAIK «ОШИБКА ШИНЫ» выдается, если некоторая операция чтения или записи в память выполняется по выровненному адресу памяти. Но в последнее время не было ошибок шины, так как современные системы (компиляторы, платформы) устранили любую жесткую и быструю потребность в данных, чтобы быть согласованными с конкретными границами, если это не специализированная аппаратная архитектура, для которой разрабатывается код.

Теперь, что касается этой конкретной проблемы, у вас есть -

(я предполагаю, что это под Linux), поэтому создайте код с ключом -g для gcc.

Затем попробуйте использовать gdb [ваш исполняемый файл]. Это должно сказать, какой функции / строке кода код выходит после ошибки. Просмотрите код этой функции / строки / до и после нее!

Мое предположение (дикое предположение) будет в том месте, где вы пишете / читаете образцы в pcm [i], потому что это, похоже, пользовательские данные типа FLAC__int32. Но эй, это может быть далеко, пока вы не отладите себя. Гудлак!

0 голосов
/ 10 июля 2011

Вы можете посмотреть на файл ядра, сказав

gdb <executable name> <corefile name> 

, а затем скажите «где», чтобы увидеть трассировку.Это поможет вам понять, что не работает (но, как заметил @JohnathanLeffler, у вас есть пара ошибок, которые можно обнаружить при проверке).

...