Maybe not helpful, but if it were me I'd std::cout the heck out
of the code to see in what sequence everything occurs. I would, do
this:
- Use some serious print lines as many places as you can,
especially on the EOF function, and the functions where you're
writing your audio source also with memory locations.
- Create output files with whatever the same data is that you
write to the media buffers, write to the files (name them each
differently each time EOF occurs close the file and reopen).
Afterwards open the files with audacity or something (especially
if they're raw PCM) and hear what they sound like.
This is how I debug stuff like this. If the output files are also
weird, then that might tell you something about what's going on.
Here's a quick and dirty (and ugly) library I wrote for just such
occasions that you can easily turn on and off.
// Intelligent debug COUT code to stop
code duplication
#ifndef DEBUGCOUTS_H
#define DEBUGCOUTS_H
#if defined( DEBUG )
#include <iomanip>
#include <iostream>
#include <string>
#include <thread>
#include <chrono>
#endif
// Define the couts
#define COUT_LOG_INFO( PREFIX ) PREFIX##_INFO() << '['
<< __LINE__ << ' ' << __PRETTY_FUNCTION__
<< "]: "
#define COUT_LOG_WARN( PREFIX ) PREFIX##_WARN() << '['
<< __LINE__ << ' ' << __PRETTY_FUNCTION__
<< "]: "
#define COUT_LOG_ERROR( PREFIX ) PREFIX##_ERROR() << '['
<< __LINE__ << ' ' << __PRETTY_FUNCTION__
<< "]: "
// Quick class for differentiating when we don't have a string
class DebugCouts_NoStringType : public std::string {}; // Make
it a string type
#endif
/**
* Prefix name of the logger functions you want.
* For example DEBUG_COUTS( MyClassFile, true )
* will make the log functions COUT_LOG_INFO, COUT_LOG_WARN,
COUT_LOG_ERROR
* For use like
* COUT_LOG_INFO( MyClassFile ) << "This will get
thinged?";
* Or just
* COUT_LOG_INFO( MyClassFile );
* Setting the second parameter ACTIVE to "false" causes
everything to be compiled out except for the iostream code which
adds some bloat
*/
#if defined( DEBUG )
#define DEBUG_COUTS( PREFIX, ACTIVE ) template<bool
ENABLED> \
class PREFIX##_Log \
{ \
public: \
template<typename STRING_TYPE=DebugCouts_NoStringType>
PREFIX##_Log( STRING_TYPE level=STRING_TYPE() ) \
{ \
if( ENABLED and
!std::is_same<STRING_TYPE,DebugCouts_NoStringType>::value
) \
{ \
auto now = std::chrono::system_clock::now(); \
auto seconds =
std::chrono::time_point_cast<std::chrono::seconds>( now );
\
auto microseconds =
std::chrono::duration_cast<std::chrono::microseconds>(
now-seconds ); \
auto t = std::chrono::system_clock::to_time_t( now ); \
char b[ 64 ]; \
if( !std::strftime( b, sizeof( b ), "%F, %T",
std::localtime( &t ) ) ) \
{ \
b[ 0 ] = 0; \
} \
std::cout << "["#PREFIX" " << level <<
' ' << b << '.' << microseconds.count()
<< "] (" << std::hex <<
std::this_thread::get_id() << std::dec << ") "; \
} \
} \
template<class T> \
PREFIX##_Log &operator <<( const T &v ) \
{ \
if( ENABLED ) \
std::cout << v; \
return( *this ); \
} \
~PREFIX##_Log() \
{ \
if( ENABLED ) \
std::cout << std::endl; \
} \
}; \
template<typename STRING_TYPE=DebugCouts_NoStringType>
PREFIX##_Log<ACTIVE> PREFIX##_ERROR( STRING_TYPE
message=STRING_TYPE() ) \
{ \
if( !ACTIVE ) \
return( PREFIX##_Log<ACTIVE>() ); \
PREFIX##_Log<ACTIVE> log( "ERROR" ); \
if(
!std::is_same<STRING_TYPE,DebugCouts_NoStringType>::value
) \
log << message << ": "; \
return( log ); \
} \
template<typename STRING_TYPE=DebugCouts_NoStringType>
PREFIX##_Log<ACTIVE> PREFIX##_WARN( STRING_TYPE
message=STRING_TYPE() ) \
{ \
if( !ACTIVE ) \
return( PREFIX##_Log<ACTIVE>() ); \
PREFIX##_Log<ACTIVE> log( "WARN" ); \
if(
!std::is_same<STRING_TYPE,DebugCouts_NoStringType>::value
) \
log << message << ": "; \
return( log ); \
} \
template<typename STRING_TYPE=DebugCouts_NoStringType>
PREFIX##_Log<ACTIVE> PREFIX##_INFO( STRING_TYPE
message=STRING_TYPE() ) \
{ \
if( !ACTIVE ) \
return( PREFIX##_Log<ACTIVE>() ); \
PREFIX##_Log<ACTIVE> log( "INFO" ); \
if(
!std::is_same<STRING_TYPE,DebugCouts_NoStringType>::value
) \
log << message << ": "; \
return( log ); \
}
#else
// Blank ones
#define DEBUG_COUTS( PREFIX, ACTIVE ) template<bool
ENABLED> \
class PREFIX##_Log \
{ \
public: \
template<typename STRING_TYPE=DebugCouts_NoStringType>
PREFIX##_Log( STRING_TYPE level=STRING_TYPE() ) \
{ \
} \
template<class T> \
PREFIX##_Log &operator <<( const T &v ) \
{ \
return( *this ); \
} \
~PREFIX##_Log() \
{ \
} \
}; \
template<typename STRING_TYPE=DebugCouts_NoStringType>
PREFIX##_Log<ACTIVE> PREFIX##_ERROR( STRING_TYPE
message=STRING_TYPE() ) \
{ \
return( PREFIX##_Log<ACTIVE>() ); \
} \
template<typename STRING_TYPE=DebugCouts_NoStringType>
PREFIX##_Log<ACTIVE> PREFIX##_WARN( STRING_TYPE
message=STRING_TYPE() ) \
{ \
return( PREFIX##_Log<ACTIVE>() ); \
} \
template<typename STRING_TYPE=DebugCouts_NoStringType>
PREFIX##_Log<ACTIVE> PREFIX##_INFO( STRING_TYPE
message=STRING_TYPE() ) \
{ \
return( PREFIX##_Log<ACTIVE>() ); \
}
#endif
Michael A. Leonetti
As warm as green tea
On 9/20/19 2:44 PM, Jonathan
Brockerville wrote:
Hi,
I'm trying to create a continuous memory player (for lack
of a better description). Here's what I'm doing. Create a
memory player with looping enabled. When it gets to EOF the
callback method is invoked. I update the memory with new audio
data and return true. This basically works, however, I keep
getting a little snippet of the previous audio data. It's as
if the callback is invoked slightly after the rewind happens.
I assumed that execution would be: play memory, EOF callback,
rewind memory, play memory, etc. That doesn't seem to be the
case. What am I getting wrong here?
I also tried disabling looping, but I couldn't figure out
how to manually rewind the memory and transmit again.
Destroying the memory player, re-creating it, and pointing at
the same but updated buffer seems heavy handed.
Should I be approaching this differently or...?
Thanks,
-brock
_______________________________________________
Visit our blog: http://blog.pjsip.org
pjsip mailing list
pjsip@xxxxxxxxxxxxxxx
http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org
|