Avatar

Please consider registering
Guest

sp_LogInOut Log In sp_Registration Register

Register | Lost password?
Advanced Search

— Forum Scope —




— Match —





— Forum Options —





Minimum search word length is 3 characters - maximum search word length is 84 characters

sp_Feed sp_TopicIcon
RackFx crashes closing oscilloscope/ stopping audio player
No permission to create posts
October 2, 2013
7:42 pm
Avatar
airbuff
Member
Members
Forum Posts: 14
Member Since:
October 2, 2013
sp_UserOfflineSmall Offline

Hello everybody!

I'm new to RackFX and to DSP in general, so please forgive possible newbie dummy questions.

First: Thank you Will for this great peace of software. I have just ended my bachelor studies in computer science with great success and I'm not sure if this would have worked out without your book, which I used a lot within my thesis.

I developed a DSP algorithm in a graphical programming language (Reaktor) and I'm in the middle of porting the algorithms to C++, using RackFX, which I think is a great tool.

In the moment, I'm testing the current state of my plugin within RackFX and it's wotking fine so far. I can load the dll, play audio through it using the audio player or the oscillator or test it using the really, really helpful analyser. Special thanks for the analyser :-)

The issue I'm running into is:
When ever I stop the audio player and whenever I close the oscilloscope, RackFX crashes. I'm not very familiar with windows. RackFX's GUI gets kind of greyed out and Windows claims it has to be closed. Sometimes (very rare), a window pops up, saying:

"Debug Asertion Failed!
Program:C:/Program Files\RackAFX\RackAFX.exe
File: f:\dd\vctools\crt_bld\self_x86\crt\src\dbgheap.c
Line: 1322
Expression: _CrtIsValidHeapPointer(pUserData)
..."

This happens reproducable after my last implementation and it does not happen with the last implementation commented. More detailed, it does not happen when the processSample() methode of my newly implemented class is commented. So prepareForPlay(), which I suspected to be called when stopping the audio player, is working fine.

I have deeply inverstigated my code and could not find any issues. Also, it does actually work while testing.

Questions:
- Which methode is called when stopping the audio player/ closing the oscilloscope? (GUI updates or whatsoever?)
- What else might cause this issue?

October 2, 2013
10:58 pm
Avatar
W Pirkle
Admin
Forum Posts: 143
Member Since:
January 28, 2017
sp_UserOfflineSmall Offline

Hi Airbuff

First, thanks for the comments on the book and RackAFX. You'll be interested to know that the new version in testing has a major upgrade to the Analyzer window including high resolution FFTs (up to 131,072 points) and windowing.

As for your problem - it appears that your DLL is crashing RackAFX. Unfortunately, Windows doesn't tell where the fault came from so it appears that RackAFX is crashing. I put a video tutorial on debugging your constructor to find crashing that looks like RackAFX but really is your DLL and the fact that you can comment out a line of code to prevent crashing also confirms this.

Closing the Analyzer doesn't actually kill the window, it stays alive but is hidden. I don't think this is your problem.

prepareForPlay() only gets called before audio streams and not afterwards so that is also not a problem. BTW you can force a call to preparForPlay() by hitting the Rest button on the toolbar (looks like a grey knob, hover the mouse over the buttons for tooltips.

Stopping the wave audio calls a method that stops the Port Audio subsystem which is what I am using. This deals with pointers to buffers of audio data and your plug-in sits right in the middle of the Port Audio stuff. I am guessing you are somehow holding a pointer to audio data. If you open the status window up and then hit the Stop button, you should see a message that says "Existing processing loop" - this is printed *after* the port audio calls. If you don't see this, then you are definitely tying up the port audio buffers somehow.

The only real way to figure this out is to debug it in realtime but setting a breakpoint would be tricky in your process function since it would be called repeatedly; though you can try using conditional breakpoints. Another option is to comment out each *line* of code in your process function. Then, uncomment them one at a time until you find the one that is crashing (you can also do this with blocks of code). Another option is to post a series of messages to the status window using sendStatusWndText() like this:

YourObject::processSample
{
sendStatusWndText("processSample() started");

do some code

sendStatusWndText("processSample() chunk 1 complete");

do some code

sendStatusWndText("processSample() chunk 2 complete");

do some code

sendStatusWndText("processSample() chunk 3 complete");

etc... until you find the faulting code.

Let us know how you fix this.

- Will

October 3, 2013
12:58 am
Avatar
airbuff
Member
Members
Forum Posts: 14
Member Since:
October 2, 2013
sp_UserOfflineSmall Offline

Hi Will,

thank you for the prompt response. I totally aggree that the issue is on my side. I simply do not get what's called when closing the oscilator window. I wasn'r aware of the Status Window. I have had a look and it states: "Exiting Processing Loop: oscillator".

The prossesing methode of the trouble maker class passes the sample by value, so I'm pretty sure I do not hold any audio data pointers:

float TapeDelay::processSample(const float x)

In the meantime I have tracked down the root of the issue. It turns out to be a C++ related issue more than a RackAFX issue. You might want to move the thread though.

The class causing the issue is representing a delay, based on a ring buffer. The idea is based on a tape delay. To track down the root of the issue, I commented all methode bodys.

The issue seems caused within the destoctor. Here is the only uncommented code in the class, constructor and destructor:

.h file:
class TapeDelay
{
private:
/** Delay in samples. Default is 0.*/
int m_n;
/** Buffer size and thus max possible delay in samples. Default is 44100. */
int m_N;
float *m_buffer;
int m_sampleRate;

RecordHead m_recordHead;
PlayHead m_playHead;.
...

.cpp file:
TapeDelay::TapeDelay(const int delayInMilliseconds, const int maxDelayInMilliseconds, const int aSampleRate)
: m_sampleRate(aSampleRate)
{
m_N = BFDspUtils::milliseconds2samples(maxDelayInMilliseconds, m_sampleRate);
setDelayTimeInMs(delayInMilliseconds);
m_buffer = new float[m_N];
resetBuffer();
m_recordHead = RecordHead(m_buffer, m_N);
m_playHead = PlayHead(m_buffer, m_N);
}
TapeDelay::~TapeDelay(void)
{
delete[] m_buffer; // here seems to be the root of the issue. If I comment this line, everything is working fine.
}

As there is no other code uncommented, I do not understand:
- What is the problem deleting the m_buffer? How I understood, the heap got corrupted somehow, which in my understanding can only happen when write-accessing the array. Which can't happen with all code commented.

Further questions:
- Why is the destructor called when closing the oscillator window?
- Why is the destructor called whenstopping the audio player?

If you have another hint, please let me know. Otherwize I'm sure I will get the buffer deleted somehow :-)

Thanks again.

October 3, 2013
1:38 am
Avatar
airbuff
Member
Members
Forum Posts: 14
Member Since:
October 2, 2013
sp_UserOfflineSmall Offline

I have found a workaroud, withoutout understanding the original problem though.

Everything is working fine creating the object on the heap:

TapeDelay *m_tapeDelay;
...
m_tapeDelay = new TapeDelay(50, 1000, 44100);
...
yL = m_tapeDelay->processSample(xL);

The issue only occurs when creating the object on the stack:

TapeDelay m_tapeDelay;
...
m_tapeDelay = TapeDelay(50, 1000, 44100);
...
yL = m_tapeDelay.processSample(xL);

October 3, 2013
7:13 pm
Avatar
W Pirkle
Admin
Forum Posts: 143
Member Since:
January 28, 2017
sp_UserOfflineSmall Offline

Hmm.

The destructor is not called when you close the oscillator window and it is not called when you stop audio, otherwise your plug-in would be dead - user control changes would not update (the GUI control changes are always updated, even when no audio is playing - they must be updating to a live object and you can verify this for yourself).

The destructor is only called when you unload the DLL; it destroys your plug-in object and frees the DLL memory space. You can also verify this by placing a breakpoint in the destructor.

Will

Forum Timezone: America/New_York

Most Users Ever Online: 36

Currently Online:
3 Guest(s)

Currently Browsing this Page:
1 Guest(s)

Top Posters:

Skyler: 47

Peter: 41

Derek: 41

clau_ste: 39

Frodson: 38

Gwen: 32

EZB: 24

lppier: 23

Msaldaña: 18

Jorge: 17

Member Stats:

Guest Posters: 1

Members: 476

Moderators: 1

Admins: 4

Forum Stats:

Groups: 11

Forums: 30

Topics: 482

Posts: 1876

Newest Members:

sam, annaharris, Marie Weaver, kev, Steven, Mr Anderson, mguy, omelc

Moderators: W Pirkle: 143

Administrators: Tom: 65, JD Young: 80, Will Pirkle: 0, W Pirkle: 143