I'm trying to do some measurements on sections of an audio signal (read as a std::vector<double>
) which involves some signal-processing using Aquila. I'm calculating the MFCC constants using the same functions as in their example, but instead of an Aquila::SineGenerator
I'm creating an Aquila::SignalSource
from the vector, using this constructor.
My function, with irrelevant code removed, is:
void measure(std::vector<double> &output_vector, std::vector<double> &audio, int start_index, int end_index) {
// Copy the raw note over.
std::vector<double> note_audio(end_index - start_index);
std::copy(audio.begin() + start_index, audio.begin() + end_index, note_audio.begin());
// Calculate the MFCC constants.
Aquila::SignalSource input(note_audio, 44100);
Aquila::Mfcc mfcc(input.getSamplesCount());
auto mfccValues = mfcc.calculate(input);
// Copy them over to the output vector.
for (int i = 0; i < mfccValues.size(); i++) {
output_vector.push_back(mfccValues[i]);
}
}
When this is run - often, but not always, the second or third time it's called - it crashes and outputs:
prog(15384,0x7fff7cafb310) malloc: *** error for object 0x7f8781863208: incorrect checksum for freed object - object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6
So, I fire up lldb and debug, setting a breakpoint at malloc_error_break
, and get this stacktrace:
(lldb) bt
* thread #1: tid = 0x23c194, 0x00007fff8f487bc0 libsystem_malloc.dylib`malloc_error_break, queue = 'com.apple.main-thread', stop reason = breakpoint 1.2
* frame #0: 0x00007fff8f487bc0 libsystem_malloc.dylib`malloc_error_break
frame #1: 0x00007fff8f4815c7 libsystem_malloc.dylib`szone_error + 386
frame #2: 0x00007fff8f482e1a libsystem_malloc.dylib`small_free_list_remove_ptr + 291
frame #3: 0x00007fff8f47f737 libsystem_malloc.dylib`szone_free_definite_size + 3429
frame #4: 0x00000001000029a5 prog-debug`std::__1::__vector_base<double, std::__1::allocator<double> >::~__vector_base() [inlined] std::__1::__deallocate(__ptr=0x00000001008f3800) + 421 at new:164
frame #5: 0x000000010000299c prog-debug`std::__1::__vector_base<double, std::__1::allocator<double> >::~__vector_base() [inlined] std::__1::allocator<double>::deallocate(this=0x0000000100307888, __p=0x00000001008f3800, (null)=6300) + 8 at memory:1636
frame #6: 0x0000000100002994 prog-debug`std::__1::__vector_base<double, std::__1::allocator<double> >::~__vector_base() [inlined] std::__1::allocator_traits<std::__1::allocator<double> >::deallocate(__a=0x0000000100307888, __p=0x00000001008f3800, __n=6300) + 24 at memory:1447
frame #7: 0x000000010000297c prog-debug`std::__1::__vector_base<double, std::__1::allocator<double> >::~__vector_base(this=0x0000000100307878) + 380 at vector:476
frame #8: 0x0000000100002e25 prog-debug`std::__1::vector<double, std::__1::allocator<double> >::~vector(this=0x0000000100307878) + 21 at vector:481
frame #9: 0x0000000100002355 prog-debug`std::__1::vector<double, std::__1::allocator<double> >::~vector(this=0x0000000100307878) + 21 at vector:481
frame #10: 0x000000010004b99c prog-debug`Aquila::MelFilter::~MelFilter() + 28
frame #11: 0x000000010004b975 prog-debug`Aquila::MelFilter::~MelFilter() + 21
frame #12: 0x000000010004b8b7 prog-debug`std::__1::__vector_base<Aquila::MelFilter, std::__1::allocator<Aquila::MelFilter> >::~__vector_base() + 279
frame #13: 0x000000010004b795 prog-debug`std::__1::vector<Aquila::MelFilter, std::__1::allocator<Aquila::MelFilter> >::~vector() + 21
frame #14: 0x000000010004b775 prog-debug`std::__1::vector<Aquila::MelFilter, std::__1::allocator<Aquila::MelFilter> >::~vector() + 21
frame #15: 0x000000010004b755 prog-debug`Aquila::MelFilterBank::~MelFilterBank() + 21
frame #16: 0x000000010004b545 prog-debug`Aquila::MelFilterBank::~MelFilterBank() + 21
frame #17: 0x000000010004b463 prog-debug`Aquila::Mfcc::calculate(Aquila::SignalSource const&, unsigned long) + 323
frame #18: 0x00000001000203b6 prog-debug`measure(the_vector=0x00007fff5fbfd8c8, audio=0x00007fff5fbfe478, start_index=7078, end_index=13378) + 1270 at measureVector.cpp:62
frame #19: 0x0000000100018eb2 prog-debug`extractVectors(vectors=0x00007fff5fbfe4e0, audio=vector<double, std::__1::allocator<double> > at 0x00007fff5fbfe478, sample_rate=44100, bg_audio=vector<double, std::__1::allocator<double> > at 0x00007fff5fbfe460, bg_sample_rate=44100, notes=0x00007fff5fbfe490) + 3234 at extractVectors.cpp:74
frame #20: 0x000000010002b915 prog-debug`train(results=0x00007fff5fbff620, training_path=std::__1::string at 0x00007fff5fbff608, bg_audio=vector<double, std::__1::allocator<double> > at 0x00007fff5fbff5f0, bg_sample_rate=44100, classes=0x00007fff5fbff638) + 5733 at train.cpp:44
frame #21: 0x00000001000211d3 prog-debug`MUSE(input_path=std::__1::string at 0x00007fff5fbff948, training_path=std::__1::string at 0x00007fff5fbff930, noise_profile_path=std::__1::string at 0x00007fff5fbff908, output_path=std::__1::string at 0x00007fff5fbff8f0) + 995 at muse.cpp:44
frame #22: 0x00000001000217fd prog-debug`main(argc=5, argv=0x00007fff5fbffab8) + 717 at muse.cpp:55
Sometimes I get that, sometimes I get other errors in the internals (you can see them here), but they all start at Aquila::Mfcc::calculate()
and usually seem to involve a destructor. I've run into errors which look similar and are due to trying to return stack-based variables (oops - it's why I'm passing in my output_vector and modifying it in the function), but I don't see that here - I'm using it, then copying over the double
values to my output vector. I've tried creating note_audio
as a pointer with new
, I've tried creating it as an array instead of std::vector
both on the stack and on the heap, to no avail.
Building C++11 on OS X Mavericks, using CMake and LLVM. As per suggestion in the comments, I've saved a Gist of the first ~300 lines of a Valgrind output (although it keeps going until >100 errors). What am I missing here?