Encoding Raw Samples

quiet_sample_t

typedef float quiet_sample_t;

All modem values generated are floating-point values between -1.0 and 1.0.

quiet_encoder

struct quiet_encoder;

typedef struct quiet_encoder quiet_encoder;

quiet_encoder_create

quiet_encoder *

quiet_encoder_create(const quiet_encoder_options *opt,

                     float sample_rate);

quiet_encoder_create creates and initializes a new libquiet encoder for a given set of options and sample rate. As libquiet makes use of its own resampler, it is suggested to use the default sample rate of your device, so as to not invoke any implicit resamplers.

Parameters

opt - quiet_encoder_options containing encoder configuration

sample_rate - Sample rate that encoder will generate at

Returns

pointer to a new encoder object, or NULL if creation failed

quiet_encoder_send

ssize_t

quiet_encoder_send(quiet_encoder *e,

                   const void *buf,

                   size_t len);

quiet_encoder_send copies the frame provided by the user to an internal transmit queue. By default, this is a nonblocking call and will fail if the queue is full. However, if quiet_encoder_set_blocking has been called first, then it will wait for as much as the timeout length specified there if the frame cannot be immediately written.

The frame provided must be no longer than the maximum frame length of the encoder. If the frame is longer, it will be rejected entirely, and no data will be transmitted.

If libquiet was built and linked with pthread, then this function may be called from any thread, and by multiple threads concurrently.

quiet_encoder_send will return 0 if the queue is closed to signal EOF.

quiet_encoder_send will return a negative value and set the last error to quiet_timedout if the send queue is full and no space was made before the timeout

quiet_encoder_send will return a negative value and set the last error to quiet_would_block if the send queue is full and the encoder is in nonblocking mode

Parameters

e - encoder object

buf - user buffer containing the frame payload

len - the number of bytes in buf

Returns

the number of bytes copied from the buffer, 0 if the queue is closed, or -1 if sending failed

quiet_encoder_set_blocking

void

quiet_encoder_set_blocking(quiet_encoder *e,

                           time_t sec,

                           long nano);

quiet_encoder_set_blocking changes the behavior of quiet_encoder_send so that it will block until a frame can be written. It will block for approximately (nano + 1000000000*sec) nanoseconds.

If sec and nano are both 0, then quiet_encoder_send will block indefinitely until a frame is sent.

This function is only supported on systems with pthread. Calling quiet_encoder_set_blocking on a host without pthread will assert false.

Parameters

e - encoder object

sec - time_t number of seconds to block for

nano - long number of nanoseconds to block for

quiet_encoder_set_nonblocking

void

quiet_encoder_set_nonblocking(quiet_encoder *e);

quiet_encoder_set_nonblocking changes the behavior of quiet_encoder_send so that it will not block if it cannot write a frame. This function restores the default behavior after quiet_encoder_set_blocking has been called.

Parameters

e - encoder object

quiet_encoder_set_emit_blocking

void

quiet_encoder_set_emit_blocking(quiet_encoder *e,

                                time_t sec,

                                long nano);

quiet_encoder_set_emit_blocking changes quiet_encoder_emit so that it will block until a frame is read. It will block for approximately (nano + 1000000000*sec) nanoseconds.

quiet_encoder_emit may emit some empty (silence) samples if one frame is available but more frames are needed for the full length of the block given to quiet_encoder_emit. That is, quiet_encoder_emit will not block the tail of one frame while waiting for the next.

If sec and nano are both 0, then quiet_encoder_emit will block indefinitely until a frame is read.

This function is only supported on systems with pthread. Calling quiet_encoder_set_blocking on a host without pthread will assert false.

Parameters

e - encoder object

sec - time_t number of seconds to block for

nano - long number of nanoseconds to block for

quiet_encoder_set_emit_nonblocking

void

quiet_encoder_set_emit_nonblocking(quiet_encoder *e);

quiet_encoder_set_emit_nonblocking changes the behavior of quiet_encoder_emit so that it will not block if it cannot read a frame. This function restores the default behavior after quiet_encoder_set_emit_blocking has been called.

Parameters

e - encoder object

quiet_encoder_clamp_frame_len

size_t

quiet_encoder_clamp_frame_len(quiet_encoder *e,

                              size_t sample_len);

quiet_encoder_clamp_frame_len enables a mode in the encoder which prevents data frames from overlapping multiple blocks of samples, e.g. multiple calls to quiet_encoder_emit. This can be very convenient if your environment cannot keep up in realtime due to e.g. GC pauses. The transmission of data will succeed as long as the blocks of samples are played out smoothly (gaps between blocks are ok, gaps within blocks are not ok).

Calling this with the size of your sample block will clamp the frame length of this encoder and toggle the is_close_frame flag which will ensure that sample blocks will always end in silence. This will never result in a frame length longer than the one provided in the creation of the encoder, but it may result in a shorter frame length.

Parameters

e - encoder object

sample_len - size of sample block

Returns

the new frame length

quiet_encoder_get_frame_len

size_t

quiet_encoder_get_frame_len(const quiet_encoder *e);

Parameters

e - encoder object

Returns

encoder's maximum frame length, e.g. the largest length that can be passed to quiet_encoder_send

quiet_encoder_emit

ssize_t

quiet_encoder_emit(quiet_encoder *e,

                   quiet_sample_t *samplebuf,

                   size_t samplebuf_len);

quiet_encoder_emit fills a block of samples pointed to by samplebuf by reading frames from its transmit queue and encoding them into sound by using the configuration specified at creation. These samples can be written out directly to a file or soundcard.

If you are using a soundcard, you will have to carefully choose the sample size block. Typically, the largest size is 16384 samples. Larger block sizes will help hide uneven latencies in the encoding process and ensure smoother transmission at the cost of longer latencies.

quiet_encoder_emit may return fewer than the number of samples requested. Unlike quiet_encoder_send, quiet_encoder_emit does not block, even when blocking mode is enabled. This is because soundcard interfaces typically require realtime sample generation.

If quiet_encoder_emit returns 0, then the transmit queue is closed and empty, and no future calls to quiet_encoder_emit will retrieve any more samples.

Parameters

e - encoder object

samplebuf - user-provided array where samples will be written

samplebuf_len - length of user-provided array

Returns

the number of samples written to samplebuf, which shall never exceed samplebuf_len. If the returned number of samples written is less than samplebuf_len, then the encoder has finished encoding the payload (its transmit queue is empty and all state has been flushed out). The user should 0-fill any remaining length if the block is to be transmitted.

If quiet_encoder_emit returns a negative length, then it will set the quiet error. Most commonly, this will happen when the transmit queue is empty and there are no frames ready to send, but the queue is still open. If and only if the queue is closed and has been completely read, quiet_encoder_emit will return 0 to signal EOF.

Errors

foo - bar baz

qux - quuux

quiet_encoder_close

void

quiet_encoder_close(quiet_encoder *e);

quiet_encoder_close closes the encoder object. This has the effect of rejecting any future calls to quiet_encoder_send. Any previously queued frames will be written by quiet_encoder_emit. Once the send queue is empty, quiet_encoder_emit will set last error to quiet_closed.

Parameters

e - encoder object

quiet_encoder_destroy

void

quiet_encoder_destroy(quiet_encoder *e);

quiet_encoder_destroy releases all resources allocated by the quiet_encoder. After calling this function, the user should not call any other encoder functions on the quiet_encoder.

Parameters

e - encoder object