Skip to content

Commit

Permalink
docs: Update API usage examples
Browse files Browse the repository at this point in the history
  • Loading branch information
gavv committed Jul 15, 2024
1 parent 26bad17 commit 991f2f0
Show file tree
Hide file tree
Showing 9 changed files with 299 additions and 55 deletions.
69 changes: 36 additions & 33 deletions docs/sphinx/api/examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,57 +5,60 @@ Examples
:local:
:depth: 2

Basic sender and receiver
-------------------------
Basic senders and receivers
---------------------------

* `basic_sender_sine_wave.c <https://github.com/roc-streaming/roc-toolkit/blob/master/src/public_api/examples/basic_sender_sine_wave.c>`_

Basic sender example.
Minimal sender:
- creates a sender and connects it to remote address
- generates a 10-second beep and writes it to the sender

This example creates a sender and connects it to remote receiver.
Then it generates a 10-second beep and writes it to the sender.
* `basic_sender_pulseaudio.c <https://github.com/roc-streaming/roc-toolkit/blob/master/src/public_api/examples/basic_sender_pulseaudio.c>`_

* `basic_sender_from_pulseaudio.c <https://github.com/roc-streaming/roc-toolkit/blob/master/src/public_api/examples/basic_sender_from_pulseaudio.c>`_
Another minimal sender:
- creates a sender and connects it to remote address
- captures audio stream from PulseAudio and writes it to the sender

Basic sender example.
* `basic_receiver_pulseaudio.c <https://github.com/roc-streaming/roc-toolkit/blob/master/src/public_api/examples/basic_receiver_pulseaudio.c>`_

This example creates a sender and connects it to remote receiver.
Then it records audio stream from PulseAudio and writes it to the sender.
Minimal receiver:
- creates a receiver and binds it to a local address
- reads audio stream from the receiver and plays it using PulseAudio

* `basic_receiver_to_pulseaudio.c <https://github.com/roc-streaming/roc-toolkit/blob/master/src/public_api/examples/basic_receiver_to_pulseaudio.c>`_

Basic receiver example.

This example creates a receiver and binds it to a known address.
Then it reads audio stream from the receiver and plays it using PulseAudio.

Network protocols
Network endpoints
-----------------

* `send_receive_rtp.c <https://github.com/roc-streaming/roc-toolkit/blob/master/src/public_api/examples/send_receive_rtp.c>`_

Send and receive samples using bare RTP.
* `send_recv_rtp.c <https://github.com/roc-streaming/roc-toolkit/blob/master/src/public_api/examples/send_recv_rtp.c>`_

This example creates a receiver and binds it to an RTP endpoint.
Then it creates a sender and connects it to the receiver endpoint.
Then it starts writing audio stream to the sender and reading it from receiver.
Sending and receiving using bare RTP without extensions:
- creates a receiver and binds it to a single RTP endpoint
- creates a sender and connects it to the receiver endpoint
- one thread writes audio stream to the sender
- another thread reads audio stream from receiver

* `send_receive_rtp_with_fecframe.c <https://github.com/roc-streaming/roc-toolkit/blob/master/src/public_api/examples/send_receive_rtp_with_fecframe.c>`_
* `send_recv_rtp_rtcp_fec.c <https://github.com/roc-streaming/roc-toolkit/blob/master/src/public_api/examples/send_recv_rtp_rtcp_fec.c>`_

Send and receive samples using RTP and FECFRAME.
Sending a receiving using RTP + FECFRAME + RTCP.

This example is like `send_receive_rtp.c`, but it creates two endpoints:
- the first, source endpoint is used to transmit audio stream
- the second, repair endpoint is used to transmit redundant stream
This example is like ``send_recv_rtp.c``, but it uses three endpoints (on both sender and receiver):
- source endpoint is used to transmit audio stream (via RTP)
- repair endpoint is used to transmit redundant stream for loss recovery (via FECFRAME)
- control endpoint is used to transmit bi-directional control traffic (via RTCP)

The redundant stream is used on receiver to recover lost audio packets.
This is useful on unreliable networks.
This is the recommended way to use the library as it unlocks all the available features like loss recovery, feedback, metrics, etc.

Miscellaneous
-------------

* `uri_manipulation.c <https://github.com/roc-streaming/roc-toolkit/blob/master/src/public_api/examples/uri_manipulation.c>`_
* `misc_uri_manipulation.c <https://github.com/roc-streaming/roc-toolkit/blob/master/src/public_api/examples/misc_uri_manipulation.c>`_

Demonstrates how to build endpoint URI and access its individual parts using ``roc_endpoint`` API.

* `misc_logging.c <https://github.com/roc-streaming/roc-toolkit/blob/master/src/public_api/examples/misc_logging.c>`_

Demonstrates how to configure log level and handler.

URI manipulation example.
* `misc_version.c <https://github.com/roc-streaming/roc-toolkit/blob/master/src/public_api/examples/misc_version.c>`_

This example demonstrates how to build endpoint URI and access its individual parts.
Demonstrates how to check library version at compile-time and run-time.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Then it reads audio stream from the receiver and plays it using PulseAudio.
*
* Building:
* cc basic_receiver_to_pulseaudio.c -lroc -lpulse-simple
* cc basic_receiver_pulseaudio.c -lroc -lpulse-simple
*
* Running:
* ./a.out
Expand All @@ -28,6 +28,7 @@
#define MY_RECEIVER_IP "0.0.0.0"
#define MY_RECEIVER_SOURCE_PORT 10101
#define MY_RECEIVER_REPAIR_PORT 10102
#define MY_RECEIVER_CONTROL_PORT 10103

/* Signal parameters. */
#define MY_SAMPLE_RATE 44100
Expand Down Expand Up @@ -123,6 +124,26 @@ int main() {
oops();
}

/* Bind receiver to the control (RTCP) packets endpoint. */
roc_endpoint* control_endp = NULL;
if (roc_endpoint_allocate(&control_endp) != 0) {
oops();
}

roc_endpoint_set_protocol(control_endp, ROC_PROTO_RTCP);
roc_endpoint_set_host(control_endp, MY_RECEIVER_IP);
roc_endpoint_set_port(control_endp, MY_RECEIVER_CONTROL_PORT);

if (roc_receiver_bind(receiver, ROC_SLOT_DEFAULT, ROC_INTERFACE_AUDIO_CONTROL,
control_endp)
!= 0) {
oops();
}

if (roc_endpoint_deallocate(control_endp) != 0) {
oops();
}

/* Initialize PulseAudio parameters. */
pa_sample_spec sample_spec;
memset(&sample_spec, 0, sizeof(sample_spec));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Then it records audio stream from PulseAudio and writes it to the sender.
*
* Building:
* cc basic_sender_sine_wave.c -lroc
* cc basic_sender_pulseaudio.c -lroc
*
* Running:
* ./a.out
Expand All @@ -29,6 +29,7 @@
#define MY_RECEIVER_IP "127.0.0.1"
#define MY_RECEIVER_SOURCE_PORT 10101
#define MY_RECEIVER_REPAIR_PORT 10102
#define MY_RECEIVER_CONTROL_PORT 10103

/* Signal parameters */
#define MY_SAMPLE_RATE 44100
Expand Down Expand Up @@ -124,6 +125,26 @@ int main() {
oops();
}

/* Connect sender to the receiver control (RTCP) packets endpoint. */
roc_endpoint* control_endp = NULL;
if (roc_endpoint_allocate(&control_endp) != 0) {
oops();
}

roc_endpoint_set_protocol(control_endp, ROC_PROTO_RTCP);
roc_endpoint_set_host(control_endp, MY_RECEIVER_IP);
roc_endpoint_set_port(control_endp, MY_RECEIVER_CONTROL_PORT);

if (roc_sender_connect(sender, ROC_SLOT_DEFAULT, ROC_INTERFACE_AUDIO_CONTROL,
control_endp)
!= 0) {
oops();
}

if (roc_endpoint_deallocate(control_endp) != 0) {
oops();
}

/* Initialize PulseAudio parameters. */
pa_sample_spec sample_spec;
memset(&sample_spec, 0, sizeof(sample_spec));
Expand Down
21 changes: 21 additions & 0 deletions src/public_api/examples/basic_sender_sine_wave.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#define MY_RECEIVER_IP "127.0.0.1"
#define MY_RECEIVER_SOURCE_PORT 10101
#define MY_RECEIVER_REPAIR_PORT 10102
#define MY_RECEIVER_CONTROL_PORT 10103

/* Signal parameters */
#define MY_SAMPLE_RATE 44100
Expand Down Expand Up @@ -138,6 +139,26 @@ int main() {
oops();
}

/* Connect sender to the receiver control (RTCP) packets endpoint. */
roc_endpoint* control_endp = NULL;
if (roc_endpoint_allocate(&control_endp) != 0) {
oops();
}

roc_endpoint_set_protocol(control_endp, ROC_PROTO_RTCP);
roc_endpoint_set_host(control_endp, MY_RECEIVER_IP);
roc_endpoint_set_port(control_endp, MY_RECEIVER_CONTROL_PORT);

if (roc_sender_connect(sender, ROC_SLOT_DEFAULT, ROC_INTERFACE_AUDIO_CONTROL,
control_endp)
!= 0) {
oops();
}

if (roc_endpoint_deallocate(control_endp) != 0) {
oops();
}

/* Generate sine wave and write it to the sender. */
size_t i;
for (i = 0; i < MY_SINE_DURATION / MY_BUFFER_SIZE; i++) {
Expand Down
84 changes: 84 additions & 0 deletions src/public_api/examples/misc_logging.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/* Logging configuration example.
*
* This example demonstrates how to configure logging.
*
* Building:
* cc misc_logging.c -lroc
*
* Running:
* ./a.out
*
* License:
* public domain
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <roc/context.h>
#include <roc/log.h>

#define oops() \
do { \
fprintf(stderr, "oops: failure on %s:%d\n", __FILE__, __LINE__); \
fprintf(stderr, "exiting!\n"); \
exit(1); \
} while (0)

static void my_log_handler(const roc_log_message* message, void* argument) {
const char* lvl = NULL;

switch (message->level) {
case ROC_LOG_ERROR:
lvl = "ERROR";
break;

case ROC_LOG_INFO:
lvl = "INFO";
break;

case ROC_LOG_NOTE:
lvl = "NOTE";
break;

case ROC_LOG_DEBUG:
lvl = "DEBUG";
break;

case ROC_LOG_TRACE:
lvl = "TRACE";
break;

default:
lvl = "UNKNOWN";
break;
}

printf("level=%s module=%s time=%lld pid=%llu tid=%llu text=%s\n", lvl,
message->module, message->time, message->pid, message->tid, message->text);
}

int main() {
/* Allow all log message starting from DEBUG level and higher.
*/
roc_log_set_level(ROC_LOG_DEBUG);

/* Set custom handler for log messages.
*/
roc_log_set_handler(my_log_handler, NULL);

/* Do something to trigger some logging.
*/
roc_context_config context_config;
memset(&context_config, 0, sizeof(context_config));
roc_context* context = NULL;
if (roc_context_open(&context_config, &context) != 0) {
oops();
}
if (roc_context_close(context) != 0) {
oops();
}

return 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* This example demonstrates how to build endpoint URI and access its individual parts.
*
* Building:
* cc uri_manipulation.c -lroc
* cc misc_uri_manipulation.c -lroc
*
* Running:
* ./a.out
Expand Down
55 changes: 55 additions & 0 deletions src/public_api/examples/misc_version.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/* Logging configuration example.
*
* This example demonstrates how to check library version.
*
* Building:
* cc misc_version.c -lroc
*
* Running:
* ./a.out
*
* License:
* public domain
*/

#include <stdio.h>

#include <roc/version.h>

int main() {
/* Inspect compile-time library version, defined in header file.
*/
printf("compile-time version: %u.%u.%u, version code: %u\n", ROC_VERSION_MAJOR,
ROC_VERSION_MINOR, ROC_VERSION_PATCH, ROC_VERSION);

#if ROC_VERSION >= ROC_VERSION_CODE(0, 3, 0)
printf("compile-time version is >= 0.3.0\n");
#else
printf("compile-time version is < 0.3.0\n");
#endif

/* Inspect run-time library version, returned by a function.
*/
roc_version version;
roc_version_load(&version);

printf("run-time version: %u.%u.%u, version code: %u\n", version.major, version.minor,
version.patch, version.code);

if (version.code >= ROC_VERSION_CODE(0, 3, 0)) {
printf("run-time version is >= 0.3.0\n");
} else {
printf("run-time version is < 0.3.0\n");
}

/* Compare compile-time and run-time version.
* They may differ when using a shared library.
*/
if (version.code == ROC_VERSION) {
printf("compile-time and run-time versions match\n");
} else {
printf("compile-time and run-time versions differ\n");
}

return 0;
}
Loading

0 comments on commit 991f2f0

Please sign in to comment.