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