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 :)
Monday, September 24, 2012
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.
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)
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! :)
Monday, September 3, 2012
Sunday, September 2, 2012
Raspberry pi + Dexter improvements
Getting better!
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)
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)
Subscribe to:
Posts (Atom)