Welcome, Guest
Username: Password: Remember me
In this category you can discuss how to connect a third party software (loggers, CW Skimmer etc.) or devices to ExpertSDR3.

TOPIC: TCI Audio Stream example

TCI Audio Stream example 18 Oct 2020 19:55 #1

  • iw7dmh
  • iw7dmh's Avatar
  • OFFLINE
  • Posts: 113
  • Thank you received: 63
Hello,

I am wondering if someone can publish a code example, in any programming language, that can sends via TCI stream a .wav audio file to EESDR.
The idea is sending to the rig pre-recorded messages without VAC support.
The attached picture is a part of the TCI manual that is not very clear.

Any support will be appreciated

73' Enzo
iw7dmh
Attachments:
Last Edit: 18 Oct 2020 19:56 by iw7dmh.
The administrator has disabled public write access.

TCI Audio Stream example 19 Oct 2020 11:27 #2

  • LA3QMA
  • LA3QMA's Avatar
  • OFFLINE
  • Posts: 51
  • Thank you received: 23
This is what i got a few days/weeks ago:

If I understand you correctly you need to transfer / receive audio stream between your application and ESDR2.
To do that you'll need to use commands AUDIO_START and AUDIO_STOP.
Stream exchange algorithm looks as follows:
1. After sending the command AUDIO_START, ESDR2 starts to send audio to the client (binary message).
Client receives the data and then decides what to do with it, process or ignore it.
2. When ESDR2 turns to TX, it sends binary message (TX chrono) which tells you that the client must send audio stream frame in ESDR2.
This algorithm is required for a continuous, unstoppable exchange of audio data.
3. When TCIMacro gets a TX_CHRONO binary frame, it should automatically answer with TX_AUDIO frame, which contains audio stream for TX mode.

So far i got help from a friend and i'm splitting the audio in blocks/frames but i have not yet tried to send it trough the TCI.
Not sure if the data should be big/LitleEndian. And my understanding is that we should send the binary each time TCI responds with "TX chrono"

If/when i have more information i'll post but yest it would be nice if someone can post an example in whatever language. I'm using GOLANG.
The administrator has disabled public write access.
The following user(s) said Thank You: iw7dmh

TCI Audio Stream example 23 Oct 2020 20:07 #3

  • iw7dmh
  • iw7dmh's Avatar
  • OFFLINE
  • Posts: 113
  • Thank you received: 63
Hello Kai,

thank you very much for your answer.
I am wondering if you sniffed the network stream using wireshark or something else. After the AUDIO START command I can't find a way to identify the TX-CHRONO packet.
Anyway this is a good starting point and I hope someoneg else can read the message (hopefully Yuri, UT4LW that is mastering the I/Q stream from years now).

Thank you again
Best 73'
Enzo
The administrator has disabled public write access.

TCI Audio Stream example 06 Feb 2021 11:07 #4

  • dl3ney
  • dl3ney's Avatar
  • OFFLINE
  • Posts: 5
  • Thank you received: 10
Hello Enzo,

there is an example in the github repo of the TCI Interface definition written in C++ for Qt. The following method shows what you have to do when you receive a binary message via the websocket connection: github.com/maksimus1210/TCI/blob/0b22692ad6fdcea3f05aab89fb369ec555edf51a/projects_example/TciClient/libs/TciClient/tciclient.cpp#L150

How you get to the point where you know that you received a binary message highly depends on the language and the websocket library you are using. But this part is not TCI specific and should be documented in your websocket library.

When you have the binary message at your fingertips, do the following steps in order to handle the TX chrono message:
  1. Unmarshal the binary data into a data structure that you can handle in your language. The data comes in binary form in little endian byte order, the meaning of the bytes is perfectly described in the "typedef struct DataStream" that you posted.
  2. Check the field "type" (bytes 0x18-0x1B). If it has the value 3, you received a TX chrono message.
  3. The field "length" (bytes 0x14-0x17) contains the number of samples that is expected by ExpertSDR. You need to send a binary message through the websocket connect as a reply that uses the same data structure (typedef struct DataStream) and contains the requested number of samples. (see also github.com/maksimus1210/TCI/blob/0b22692ad6fdcea3f05aab89fb369ec555edf51a/projects_example/TciClient/libs/TciClient/tciclient.cpp#L112)

I hope this helps. Below I marked the relevant parts with comments to give some orientation in the example code.

73! Florian
void TciClient::onBinaryReceived(const QByteArray &data)
{
    t_iqData = data;
// STEP 1: unmarshal - this is rather simple in C++, as the data structure was defined in this language
    DataStream *pStream = reinterpret_cast<DataStream*>(t_iqData.data());

    if (pStream->receiver != 0u)
        return;

    if (pStream->type == IqStream) {
        m_signalIQ.resize(pStream->length/2u);
        for (quint32 i = 0u, j = 0u; i < pStream->length; ++j) {
            m_signalIQ[j].re = pStream->data[i++];
            m_signalIQ[j].im = pStream->data[i++];
        }
        emit readyReadIq();
    }
    else if (pStream->type == RxAudioStream) {
        m_signalAudio.resize(pStream->length/2u);
        for (quint32 i = 0u, j = 0u; i < pStream->length; ++j) {
            m_signalAudio[j].re = pStream->data[i++];
            m_signalAudio[j].im = pStream->data[i++];
        }
        emit readyReadAudio();
    }
// STEP 2: check the message type for TxChrono (3)
    else if (pStream->type == TxChrono) {
        qDebug() << Q_FUNC_INFO << __LINE__ << m_txTimer.elapsed();
        m_txTimer.start();
// STEP 3: reply with the required number of samples, see also https://github.com/maksimus1210/TCI/blob/0b22692ad6fdcea3f05aab89fb369ec555edf51a/projects_example/TciClient/libs/TciClient/tciclient.cpp#L112
        emit chronoTxSignal(pStream->length);
    }
}
The administrator has disabled public write access.
The following user(s) said Thank You: Rome, iw7dmh

TCI Audio Stream example 07 Feb 2021 12:56 #5

  • dl3ney
  • dl3ney's Avatar
  • OFFLINE
  • Posts: 5
  • Thank you received: 10
If you do not want to start from scratch, I wrote a client library for TCi in Go: github.com/ftl/tci There is an example for a simple two-tone generator (github.com/ftl/tci/blob/master/cmd/tone.go) which you probably can use as a starting point for your audio file sending tool that you mentioned in your original post.

73! Florian
The administrator has disabled public write access.
The following user(s) said Thank You: Rome, LA3QMA

TCI Audio Stream example 03 May 2021 12:04 #6

  • LA3QMA
  • LA3QMA's Avatar
  • OFFLINE
  • Posts: 51
  • Thank you received: 23
Florian:

Is it possible to adapt your TCI client "two tone" so be a gateway/hub...

i.e let ARDOPPC (www.cantab.net/users/john.wiseman/Documents/ARDOPC.html) connect to the "tci client" and this connects to the sunsdr?

If so other software modems like fldigi etc could gate sound back/forth trough "tci hub" to sunsdr.
Even with a small delay i think this could be useful? Or do we still need to use loopbacks etc?

Or is it better to ask the developer of ardoppc to implement the TCI?
The administrator has disabled public write access.

TCI Audio Stream example 13 May 2021 13:49 #7

  • dl3ney
  • dl3ney's Avatar
  • OFFLINE
  • Posts: 5
  • Thank you received: 10
In fact I have tried to provide the TCI audio streams via Pulse Audio sinks and sources but was not very successful in the end. Doing audio the right way is hard. And putting another piece of software in between the audio streams does not improve the situation ;-)

So I guess it is better to encourage the author of the original software to integrate TCI. It's no rocket science.

73, Florian
The administrator has disabled public write access.

TCI Audio Stream example 16 May 2021 15:39 #8

  • LA3QMA
  • LA3QMA's Avatar
  • OFFLINE
  • Posts: 51
  • Thank you received: 23
ahh qsl on that.

I'll probably make a request to fldigi and the developer of ardop.
The administrator has disabled public write access.
Time to create page: 0.085 seconds