Monday, September 24, 2012

Audio frequency problem resolved!

The latest Raspberry Pi firmware update does indeed resolve the audio frequency issue I was seeing.  My test laserdisc image file (with a continuous sine wave as the audio) now sounds smooth with no breaks or pops.

This audio testing reminded me of another audio issue that has been reported to me in the past: when the sound initially starts playing, it does not seem to be properly buffered because it kind of stutters before it gets going.  I will look into this next.  My design should've prevented this from happening so I am curious why it's not working :)

Tuesday, September 18, 2012

Pi audio issues improved

Some smart people have been working on improving the Pi's audio problems and they've made some progress (see thread linked in my previous blog entry).  I am using the latest experimental firmware and re-running my audio tests to see how accurate 44.1khz mode will be.  If it is very accurate, I won't need to mess around with any resampling.

Sunday, September 16, 2012

pi losing 2 samples every 512?

It looks like the pi (currently) has a defect in the audio where it drops 2 samples for every 512 which align quite closely to my own readings.  See this thread:


So at this point, it would make more sense for me to try to help these guts resolve this 2 sample drop issue. If I can't, then it would make sense for me to perhaps modify my code to _insert_ 2 samples for every 512 to compensate.  That would not be a very expensive hack CPU-wise so I could probably pull it off.  It would mean that the audio artifacts would still be present (2 missing samples is definitely noticeable even at this frequency) but at least the audio would tend to stay in sync for much longer (I hope).

Monday, September 10, 2012

Still working on sound

This morning I worked a bit more on getting sound smooth on the Raspberry Pi.  I made a laserdisc image file where the audio is just a continuous sine wave playing "middle C".  I observed two things:

a) when played with Dexter, the sound pops regularly so there must be a defect in my code somewhere
b) when played with ALSA test code, the sound is steady but there is a background buzzing noise that should not be present; this may be related to immature ALSA drivers

I will try it again later with "omxplayer" which is supposedly a high-performance media player to see if I can get the kind of sound I want, and if I can, I will just use the same approach for my stuff as they do.

Sunday, September 9, 2012

Got sound working with Dexter+Raspberry Pi

Yesterday I finished writing the ALSA sound code to work with Dexter and the Raspberry Pi. Upon execution, the sound proved a bit choppy (although the video still played full speed!) so I think the problem may be my interpretation of how sound buffers work in ALSA. I'll have to play around with that. Also, it could be because the slow "mix_c" function is being called which I should be able to eliminate pretty easily (no mixing is needed).

Here is oprofile's output:


samples  %        image name               symbol name
300      12.1310  dexter.bin               mix_c()
288      11.6458  [vectors] (tgid:2686 range:0xffff0000-0xffff1000) [vectors] (tgid:2686 range:0xffff0000-0xffff1000)
197       7.9660  dexter.bin               LoopCommon::Think()
121       4.8928  dexter.bin               better_select(int, select_type, unsigned int)
88        3.5584  dexter.bin               update_soundbuffer(unsigned int)
70        2.8306  dexter.bin               listener::Think(unsigned int)
55        2.2240  dexter.bin               OMXComponent::WaitForGeneric(list<boost::shared_ptr<IEvent>> const&, unsigned int)
52        2.1027  dexter.bin               PlatformRPI::SoundPause()
51        2.0623  dexter.bin               listenerThread::MainLoop()
50        2.0218  dexter.bin               main
45        1.8197  dexter.bin               MpoThreadMutex::Lock()
42        1.6983  dexter.bin               VideoObjectUtil::RenderIfNeeded(bool)
39        1.5770  dexter.bin               MpoThreadMutex::UnlockEx()
38        1.5366  dexter.bin               JPEGOpenMax::DecompressJPEGStart(unsigned char const*, unsigned int, unsigned char const*, unsigne
d int)
38        1.5366  dexter.bin               MpoPipeEx::NonBlockingRead(void*, unsigned int, unsigned int*)
38        1.5366  dexter.bin               VideoObjectGLES2::DrawRGBA()
36        1.4557  dexter.bin               ldp_img::OnVBlankStopped()
31        1.2535  dexter.bin               boost::detail::sp_counted_base::destroy()
31        1.2535  dexter.bin               game::PreThink(unsigned int)

Wednesday, September 5, 2012

Raspberry Pi + Dexter looks like a winning combo!

Good news, I hacked Dexter to use the Raspberry Pi's GPIO UART (bypassing the USB port) just to see if it would work and the results are _very_ encouraging. It would appear that the Pi is fast enough to meet Dexter's performance demands. I'll know more when I hook up audio, but I think I will spend a bit of time trying to resolve the USB port issues because I really want to use that USB port! :)

Saturday, September 1, 2012

Dexter working with Raspberry Pi

It's not quite full speed (yet) but after much work I present a video showing Dexter working with the Raspberry Pi.

Here is what the current profiler shows:


  %   cumulative   self              self     total
 time   seconds   seconds    calls   s/call   s/call  name
  8.79      0.96     0.96     5111     0.00     0.00  VideoObjectGLES2::LoadRGBAField(void const*, unsigned int)
  8.24      1.86     0.90   247893     0.00     0.00  serial_rx_char_waiting()
  4.21      2.32     0.46     5112     0.00     0.00  listener::Think(unsigned int)
  2.93      2.64     0.32                             numstr::ToStr(unsigned int, int, unsigned int)
  1.65      2.82     0.18    20472     0.00     0.00  OMXComponent::WaitForGeneric(std::list<boost::shared_ptr<IEvent>, std::allocator<boost::shared_ptr<IEvent> > > const&, unsigned int)
  1.65      3.00     0.18        1     0.18     0.45  VBIParse::VerifyVBIData(std::vector<VBI_s, std::allocator<VBI_s> >&, std::list<std::string, std::allocator<std::string> >&, std::list<std::string, std::allocator<std::string> >&, bool)
  1.56      3.17     0.17        1     0.17     0.23  VBIParse::LoadVBIData(void const*, unsigned int)
  1.47      3.33     0.16   126502     0.00     0.00  SerialStream::Read(void*, unsigned int, unsigned int)
  1.24      3.47     0.14     5112     0.00     0.00  JPEGOpenMax::DecompressJPEGStart(unsigned char const*, unsigned int, unsigned char const*, unsigned int)
  1.19      3.60     0.13    40869     0.00     0.00  OMXComponent::Lock()
  1.10      3.72     0.12     5112     0.00     0.00  JPEGOpenMax::WaitJPEGDecompressorReady(unsigned char**)
  1.10      3.84     0.12     5111     0.00     0.00  VideoObjectGLES2::DrawRGBA()
  1.10      3.96     0.12                             numstr::ToUint32(char const*, int)
  1.05      4.07     0.12    70380     0.00     0.00  boost::detail::sp_counted_base::weak_release()
  1.05      4.19     0.12    70366     0.00     0.00  boost::detail::sp_counted_base::sp_counted_base()
  0.92      4.29     0.10   202784     0.00     0.00  VBIParse::GetBestLine1718(unsigned int&, unsigned int, unsigned int, unsigned int)
  0.92      4.39     0.10   138872     0.00     0.00  boost::detail::sp_counted_base::release()
  0.82      4.48     0.09   121390     0.00     0.00  serial_rx()
  0.73      4.56     0.08     5112     0.00     0.00  Queue32::Push(unsigned int const*, unsigned int, void* (*)(void*, void const*, unsigned int))
  0.73      4.64     0.08                             MpoContainer::ReadHeader()
  0.69      4.71     0.08     5112     0.00     0.00  audio_write_buf(void const*, unsigned int, void* (*)(void*, void const*, unsigned int), unsigned int)
  0.69      4.79     0.08     5112     0.00     0.00  VideoObjectUtil::RenderIfNeeded(bool)
  0.64      4.86     0.07    34507     0.00     0.00  boost::detail::sp_counted_impl_pd<unsigned char*, boost::checked_array_deleter<unsigned char> >::dispose()
  0.64      4.93     0.07    12133     0.00     0.00  listener::ProcessPacket()
  0.64      5.00     0.07    10247     0.00     0.00  OMXComponent::WaitForEvent(OMX_EVENTTYPE, unsigned long, unsigned long, unsigned int)
  0.64      5.07     0.07     5113     0.00     0.00  OMXComponent::WaitForEventOrEmpty(OMX_EVENTTYPE, unsigned long, unsigned long, OMX_BUFFERHEADERTYPE const*, unsigned int)