What is wrong with my code? I get a "Bus Error"
I'm trying to read a file containing raw audio and encode it using FLAC. When I run the program, I get a "Bus Error". What could be wrong?
I'm compiling on OS X 10.6.8 using the following line: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;
}
Running gdb flac_enc
gives me this:
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".
warni开发者_开发技巧ng: 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".
This is strange since there is no user "benski" on my system. But I'm sure the FLAC libraries are installed properly as the example programs work perfectly.
In main()
, you don't check that the file was opened successfully. The trouble might be that you are using a null pointer in the fread()
operation. Similarly, in the write_callback()
function, your code shows an assumption of invincibility. (Also, if your callback is called more than once, the second call overwrites the data produced by the first call. That, however, is a different problem.)
You don't check how many 2-byte units were read by the fread()
. Nor do you check how much data is written by fwrite()
- was it successful?
You should be able to use gdb
or a similar debugger to see where the fault occurs.
You might be able to use valgrind
to spot the problem too.
You don't need both the if
and the while
in:
if (ok)
{
while (ok)
{
...
}
}
The loop alone is sufficient; it will be executed zero times if ok
is false on the first cycle. If there was a statement after the while
loop and before the end of the if
then both would be necessary.
In general, a SIGBUS (bus error) occurs on RISC chips when you try to access a data object that is misaligned. It is not clear which line could be causing that trouble in this code. Despite the comment about 'null pointer' earlier, that more usually ends up with a SIGSEGV (segmentation violation) than a SIGBUS.
You can look at the core file by saying
gdb <executable name> <corefile name>
and then say "where" to see the traceback. This will help you see what's failing (but as @JohnathanLeffler noted, you have a couple of bugs that can be spotted by inspection).
Do let know more details while you expect some pointers to solve your problem, like - which platform, compiler, compiler options(whether any optimization was turned on etc..).
AFAIK a 'BUS ERROR' is thrown up if some memory read or write operation is done at a unaligned memory address. But haven't seen a bus error recently since modern systems(compilers, platforms) have removed any hard and fast need on data to be aligned to specific boundaries, unless it is a specialized hardware architecture the code is being developed for.
Now as to this particular problem you have -
(I assume it is under Linux), so Build the code with -g switch for gcc.
Then try using gdb [your executable]. This should tell which function/code line the code exits after the error. Review the code from that function/line/before and after it!
My guess(wild guess) would be where you write/read the samples to pcm[i] because it seems to be a user defined data of type FLAC__int32. But hey this could be far off, until you debug yourself. Goodluck!
精彩评论