Jan 26, 2016

Whoa, that was fast! [Rust]

Browsing through Rust tutorial book's chapter Rust Inside Other Languages I was wandering, why the sample is running kind of slow (in non-release compilation): running a ten times slower than equivalent Delphi source.

Lets take a look at disassembled code for this fragment:

      for _ in 0..5_000_000 {

If you know that Rust's for is actually a syntax sugar for iterators, the result should no be so surprising:


        mov     dword ptr [rbp - 128], 0 // starting value
        mov     dword ptr [rbp - 124], 5000000 // ending value
        mov     rdi, qword ptr [rbp - 128]
        call    IntoIterator_into_iter
        ....
        mov     qword ptr [rbp - 264], rdi // iterator

Later Iterator::next() method will be called in a loop, returning Some(_) (actual value is ignored) or None, when iterator is done:


        mov     rdi, qword ptr [rbp - 264] // iterator
        call    Iterator_next
        mov     qword ptr [rbp - 152], rax // Option
        mov     qword ptr [rbp - 160], rax // 
        mov     ecx, dword ptr [rbp - 160]
        sub     ecx, 1
        ...
        je      loop_body
        jmp     break


The call to Iterator::next() is costly, it is far from as simple as "inc eax", that is why sample is running so slow.

One interesting note is what happening when you compile with --release switch. Lets take a look at our iterator loop:


        mov     rax, 004C4B400000001h    // hex 4C4B40 is 5000000 in decimal
        mov     [rsi], rax

Well, apparently compiler has outsmarted the programmer.


Whoa, that was fast!

Apr 27, 2012

ASIO Interface

There are several audio engines available under Windows.

Waveform Audio (MME) — the old one, still provides simple and clean API, working anywhere from Windows 3.0 to Windows 7 and even Windows CE.

DirectShow (DirectSound) — powerful architecture with hardware integration.

Core Audio — new audio interface introduced in Windows Vista.

ASIO — driver protocol specified by Steinberg. Its main purpose it to achieve minimal possible latency, which is important for professional applications. Many hardware manufacturers provide ASIO drivers for their products. And if they don't, there is ASIO4ALL.

ASIO API is based on COM technology, and according to Ross Bencina was unfortunately declared with thiscall calling convention.Not many compilers support it, and for Delphi you have no other option, but to use built-in assembler:

// --  --
function unaAsioDriver.controlPanel(): ASIOError;
begin
{$IFDEF CPU64 }
  result := f_asio.controlPanel();
{$ELSE }
  asm
    mov    eax, [self]
    mov    ecx, [eax][f_asio]
    mov    eax, [ecx]
    call   dword ptr [eax + cofs_controlPanel]
    //
    mov    result, eax
  end;
{$ENDIF CPU64 }
end;
where cofs_controlPanel is a displacement for ControlPanel entry point in IASIO interface. Fortunately x64 target uses one standard convention.

ASIO is based on I/O buffers and callbacks. When buffers are filled with recorded audio, a BufferSwitch callback is called, so you have a chance to read fresh data and provide ASIO with new data for playback there. Here is the prototype:

procedure(index: long; processNow: ASIOBool); cdecl;
index specifies buffer index being reported.

There is no way to get IASIO driver instance in callback, so if you open two or more devices at once, you will need two or more different callbacks.

There are plenty of audio sample formats defined in ASIO, so you have to deal with all kind of conversion from one format to another (16 to 24, MSB to LSB and so on).

Samples are organized into buffers, and buffers belong to channels. Each channel could be input or output. That makes it easy to access any sample in any channel at any time (bearing in mind original sample format).

Overall, despite some drawbacks mentioned above, ASIO is a simple and efficient way to record and playback multi-channel audio with a minimal latency.

Feb 22, 2012

RTSP and STUN

RTSP is old but still good. Flexible HTTP-like request/response model makes it easy to create custom applications based on it.

There is one drawback though, which I found impossible to overcome with standard means. When client sends a SETUP request, it should provide transport options via Transport header:

Transport: RTP/AVP;unicast;client_port=4588-4589

The problem is, client may not know its ports. That is because NAT may change the ports when packets are passing through it back and forth.

OK, that is why STUN was defined and should be used, right? But even with STUN it could be impossible. First, STUN server should be running on the same host where RTP will source will be located. Second, STUN server should be running on the same port as RTP source! Again, that is because NAT may change ports. Even when you send a packet from the same socket to the same host, but to different port, source port may change.

Here is what happening:

1) Client binds two sockets to local ports, say 25004 and 25005, and sends two packet to STUN host at port 3478. NAT changes the original client ports to something else, say 35004 and 35005. And those ports are reported back to client by STUN server.

2) Client sends SETUP request to RTSP server, saying it will use ports 35004 and 35005 for RTP/RTCP:

Transport: RTP/AVP;unicast;client_port=35004-35005

3) RTSP server setups an RTP source and starts streaming to client host at ports 35004-35005. Client receives RTP/RTCP packets, so far so good.

4) Now its time for client to send RTCP Receiver Report packet to RTP source, so it will not timeout the client. Client sends a packet from local port 25005 to remote port 5005, in hope NAT will change the source port to 35005, same as it did for STUN packet. But some NATs may be paranoid enough to change the source port to something else, when destination port is different (even though destination host is the same). I have no idea why they do that, but I saw it happen some times.

5) RTCP at source host will receive RR packet from client host, but from an unexpected port (not from 35005). Because there are no bindings between RTSP session and RTP source, it could be impossible for it to map a packet from unexpected port with existing session. And that will lead to removing the client from destinations.

So, unless you are running STUN and RTCP at the same port, there is a possibility for client to be timed out even if it sends RR packets.

What we use is simple (but non-standard!) additional field in Transport header:

Transport: RTP/AVP;unicast;SSRC=1276485;client_port=35004-35005

Client reports its SSRC when establishing a session, so RTP source may be presented with strong binding between RTSP session and RTP destination. Now, even when receiving an RR packet from unexpected port, it can map it to existing session by SSRC included in the packet.

If this field in not provided, source RTCP will simply assume the port provided by client in SETUP request will not change.

Some NATs may modify original SETUP request, if they recognize the RTSP protocol, which simply adds another level of confusion. Disable STUN functionality in client if your router is one of those.

Our new RTSP sample is running at our new development host avoxum.com at port 1500 and is ready to serve local files or re-broadcast remore stream. There is no sound card there, so live recording will not work.

Jan 11, 2012

RegEx library

As a part of SIP NAPTR lookup you may need to do a regex replacement.

Since Delphi up to 2010 does not include regex library, there was no other way but to write our own:

http://lakeofsoft.com/regex/

It was fun creating it, and I hope it would be fun using it.
Any comments and suggestions are welcome.

Dec 14, 2011

VCX December Beta

VCX Beta version was released, it brings x64 binaries and new built-in codecs.

I recommend trying VCX Beta Demo x64 first, it has two samples compiled in VS 2008 C# for x64 CPU.

The major issue with x64 version is that it cannot be hosted in 32-bit IDE, such as VS 2008/2010.

There are two options:

  • create VCX controls in run-time, as in our IPReceiver64/IPTransmitter64 samples, located in vs2008/c#/_x64/ folder
  • host x86 VCX library in IDE, but compile for x64 CPU. This requires having both x86 and x64 versions installed

In either case, x64 should be working same as x86 version, except for external codec libraries, such as CELT and Speex. Only MP3 encoding/decoding is currently supported in x64 version, with help of lame_enc.dll and libmpg123-0.dll libraries. All built-in codecs should be working fine in x64.

Unfortunately x64 release has a bit different registration module, so you will need a separate serial for it. If you already have a license for x86/ANSI version, please contact us for a free x64 license.

Oct 30, 2011

to x64 or not to x64

With new release of RAD Studio (XE2) Embarcadero opens a few more horizons for long forgotten Delphi developers. Now they can finally compile "Hello, World!" as x64 binary (only 6 years passed since first AMD64 chip, why so hasty?) and even target the OS X.

The switch to x64 does not come easy, though. The size of Integer and Cardinal is still 4 bytes, so if you get used to write the code like Cardinal(@val), in hope that Cardinal will follow native CPU expansion (as it was when Integer got expanded from 16 to 32 bits from Delphi 1 to Delphi 2), you fail.

How should you code instead? Pick one: UIntPtr(@val) or NativeUInt(@val). Huh? Who are these guys, you ask? Ask Delphi 2010 Help instead, it has a whole pile of information about them (2 random pages in total, actually).

For VC another challenge was to find the x64 version of codec libraries we are supporting. So far the Lame and mpg123 libraries are fine with x64, SpeeX and CELT would be fine hopefully soon.

I was having a great fun with new MPEG-TS demuxer code, hope you will find it fun to use.

The reason the FFT bands component was expanded is a new FFT code I have created for another project, which will hopefully find its place among LoS products soon. The code is pretty fast, so I decided to rebuild the bands display as well. If you find the dB scale rather confusing, I'm sorry, was doing my best.

As a part of Demos testing have compiled ANSI version of them (using Delphi 7) and was pretty surprised that most of them works fine under Windows 98.

No OS X news, haven't unpacked my MacBook Air yet (actually, haven't bought it yet).

More news to come, have fun coding with new RC of VC!

Apr 24, 2011

VCX maintenance release

Today we have released new version of VCX library.

It accumulates the updates from VC components made during last 8 months.

The library was recompiled and tested, samples were left almost the same as before, we will be working on new features in next releases. Beta page will got updated soon.

VS 2010 should run samples from VS 2008 without issues, if you find any, please let us know.

If your license for free updates is still valid, simply download the setup application from the URL provided in your registration email and use same name/serial.

If your license has expired you are welcome to download Demo version and see if you need the update. You can order another year of free updates with 50% discount of regular price. Contact us for coupon codes.

As a reminder, we have RTP radio streaming working 24/7 at this URI:

rtp://lakeofsoft.dyndns-server.com:5006/

Currently streaming with CELT codec. Try ipReceiver sample to tune in.

Wish you a pleasant development with our library.
Oleksandr Shamray

Apr 14, 2011

VC 2.5.2011.04

New release of VC components is ready to be downloaded and installed.

Includes many bug fixes we were working on last months, and couple of new features.

RTP Transmitter and Receiver when communicating over multicast session could have TTL specified via SDP.

New playback code would hopefully provide better quality of audio, with less clicks and other artifacts.

New RTP features, like round-trip time measurement between participants and periodic "pings" over RTP port will help with connection problem diagnostic.

RTP Conference Server now allows one user to participate in several rooms at the same time. New userStrictlyInOneRoom property is responsible for this. User can now also join another room without disconnecting from Server.

As usual, any upcoming fixes will be listed in developers section, make sure you are using the latest release.

Jan 19, 2011

VC 2.5.2011.01 update is ready

Now with better RTCP integration between RTP Conference Clients and Server, it has many vital communication problems fixed.

The streaming logic of IPReceiver and IPTransmitter was switched. IPTransmitter is more like a server now, and IPReceiver is more like a client. Good news is that IPTransmitter can dynamically stream to many receivers, maintaining timeouts and other stuff. And IPReceiver now makes NAT holes when started, so it could communicate with IPTransmitter from behind the firewall without additional configuration.

And if you need "old style" streaming of IPReceiver and IPTransmitter, there is a new sample: IPStreamPusher. Pretty simple for now, probably be extended later with more features.

And we are glad to announce another public service from Lake of Soft. This time it is a Ukrainian radio, re-broadcast with our vcIPTransmitter sample 24/7. Point your IPReceivers to rtp://lakeofsoft.dyndns-server.com:5006 and enjoy the fun.

Dec 30, 2010

VC 2.5.2010.12

New release of VC components is ready.
Now with full RTCP support, Git repository, Freeware version and new IP streaming components.

P.S. 31 Dec 2010. That was close.

Dec 1, 2010

Jul 19, 2010

VCX Library 3.0.2010.07 released

New release of VCX library is now available for download.

Includes samples and documentation for new components:

http://lakeofsoft.com/vcx/doc/gen_history.html

If you have a latest Beta key, it should be working with this release as well.

For Vista/7 installation issues, please read new instructions.

New simple linking schema also worth to be mentioned.

Thank you for reading our blog, stay tuned for more upcoming updates.

Jun 26, 2010

VCX Library 3.0.2010.06 Beta released

New beta release of VCX library is now available for download:

http://lakeofsoft.com/vcx/beta.html

It includes new IPTransmitter/IPReceiver/RTPConfServer and RTPConfClient components.

License mode was changed, so if you already have a license, please contact us for update. All licenses for new release will be update free of charge.

We are updating the documentation now, after that that beta version will became a new release.

Mar 27, 2010

VC 2.5.2010.03 is here

We are glad to announce a long-awaited update for our VC components, with the following new major features:

- new RAW/RTP streaming components: TunaIPReceiver and TunaIPTransmitter. Two new samples show how to use them for streaming.

- new RTP-based conference server and client components: TunaConfRTPserver and TunaConfRTPclient. New RTP conference samples introduce conference system designed for large number of participants.

Read more in-depth details of update in our newsletter.

Jan 11, 2010

Public sources

As the number of Object Pascal wrappers we have for well-know libraries grows, we decided to release them for public domain in hope they would be useful for many developers.

Right now you can download the Monkey Audio library API wrapper with some samples included (like apeAnalyze, apeCompress and apeDecompress). Just follow the audio\ape folder of our SVN repository. If you do not use SVN, you can download a tarball with all the sources required.

Visit our project home page to stay tuned with further public releases:
http://sourceforge.net/projects/lospublic/