Paraslash Audio Streaming | |
About News Download Documentation Development |
Paraslash's mood handling functions. More...
#include <regex.h>
#include <osl.h>
#include <lopsub.h>
#include "para.h"
#include "error.h"
#include "string.h"
#include "afh.h"
#include "afs.h"
#include "list.h"
Functions | |
int | mp_init (const char *definition, int nbytes, struct mp_context **result, char **errmsg) |
Initialize the mood parser. More... | |
bool | mp_eval_row (const struct osl_row *aft_row, struct mp_context *ctx) |
Determine whether the given audio file is admissible. More... | |
void | mp_shutdown (struct mp_context *ctx) |
Deallocate the resources of a mood parser. More... | |
int | mood_check_callback (struct afs_callback_arg *aca) |
Check all moods for syntax errors. More... | |
_static_inline_ int64_t | update_quadratic_deviation (int64_t n, int64_t old_qd, int64_t old_val, int64_t new_val, int64_t old_sum) |
Compute the new quadratic deviation in case one element changes. More... | |
void | mood_unload (struct mood_instance *m) |
Free all resources of a mood instance. More... | |
int | mood_load (const char *mood_name, struct mood_instance **result, char **msg) |
Populate a score table with admissible files for the given mood. More... | |
int | mood_loop (struct mood_instance *m, osl_rbtree_loop_func *func, void *data) |
Iterate over the admissible files of a mood instance. More... | |
int | moods_event_handler (enum afs_events event, __a_unused struct para_buffer *pb, void *data) |
Notification callback for the moods table. More... | |
Paraslash's mood handling functions.
int mp_init | ( | const char * | definition, |
int | nbytes, | ||
struct mp_context ** | result, | ||
char ** | errmsg | ||
) |
Initialize the mood parser.
This allocates and sets up the internal structures of the mood parser and creates an abstract syntax tree from the given mood definition. It must be called before mp_eval_row() can be called.
The context pointer returned by this function may be passed to mp_eval_row() to determine whether an audio file is admissible.
definition | A reference to the mood definition. |
nbytes | The size of the mood definition. |
result | Opaque context pointer is returned here. |
errmsg | Optional error message is returned here. |
It's OK to pass a NULL pointer or a zero sized buffer as the mood definition. This corresponds to the "dummy" mood for which all audio files are admissible.
The error message pointer may also be NULL in which case no error message is returned. Otherwise, the caller must free the returned string.
References mp_free_ast(), PARA_NOTICE_LOG, and zalloc().
bool mp_eval_row | ( | const struct osl_row * | aft_row, |
struct mp_context * | ctx | ||
) |
Determine whether the given audio file is admissible.
aft_row | The audio file to check for admissibility. |
ctx | As returned from mp_init(). |
If the mood parser was set up without an input buffer (dummy mood), this function returns true (without looking at the audio file metadata) to indicate that the given audio file should be considered admissible.
References mp_eval_ast().
void mp_shutdown | ( | struct mp_context * | ctx | ) |
Deallocate the resources of a mood parser.
This function frees the abstract syntax tree which was created by mp_init().
ctx | As returned from mp_init(). |
It's OK to pass a NULL pointer, in which case the function does nothing.
References mp_free_ast().
int mood_check_callback | ( | struct afs_callback_arg * | aca | ) |
Check all moods for syntax errors.
aca | Output goes to ->pbout, errors to ->fd on the error band. |
References BLOBCOL_ID, osl(), para_printf(), and afs_callback_arg::pbout.
_static_inline_ int64_t update_quadratic_deviation | ( | int64_t | n, |
int64_t | old_qd, | ||
int64_t | old_val, | ||
int64_t | new_val, | ||
int64_t | old_sum | ||
) |
Compute the new quadratic deviation in case one element changes.
n | Number of elements. |
old_qd | The quadratic deviation before the change. |
old_val | The value that was replaced. |
new_val | The replacement value. |
old_sum | The sum of all elements before the update. |
Given n real numbers a_1, ..., a_n, their sum S = a_1 + ... + a_n, their quadratic deviation
q = (a_1 - S/n)^2 + ... + (a_n - S/n)^2,
and a real number b, the quadratic deviation q' of a_1,...a_{n-1}, b (ie. the last number a_n was replaced by b) may be computed in O(1) time in terms of n, q, a_n, b, and S as
q' = q + d * s - (2 * S + d) * d / n = q + d * (s - 2 * S / n - d /n),
where d = b - a_n, and s = b + a_n.
Example: n = 3, a_1 = 3, a_2 = 5, a_3 = 7, b = 10. Then S = 15, q = 8, d = 3, s = 17, so
q + d * s - (2 * S + d) * d / n = 8 + 51 - 33 = 26,
which equals q' = (3 - 6)^2 + (5 - 6)^2 + (10 - 6)^2.
void mood_unload | ( | struct mood_instance * | m | ) |
Free all resources of a mood instance.
m | As obtained by mood_load(). If NULL, unload the current mood. |
It's OK to call this with m == NULL even if no current mood is loaded.
int mood_load | ( | const char * | mood_name, |
struct mood_instance ** | result, | ||
char ** | msg | ||
) |
Populate a score table with admissible files for the given mood.
This consults the mood table to initialize the mood parser with the mood expression stored in the blob object which corresponds to the given name. A score table is allocated and populated with references to those entries of the audio file table which evaluate as admissible with respect to the mood expression. For each audio file a score value is computed and stored along with the file reference.
mood_name | The name of the mood to load. |
result | Opaque, refers to the mood parser and the score table. |
msg | Error message or mood info is returned here. |
If the mood name is NULL, the dummy mood is loaded. This mood regards every audio file as admissible.
A NULL result pointer instructs the function to operate on the current mood. That is, on the mood instance which is used by the server to select the next audio file for streaming. In this mode of operation, the mood which was active before the call, if any, is unloaded on success.
If result is not NULL, the current mood is unaffected and *result points to an initialized mood instance on success. The caller can pass this reference to mood_loop() to iterate over the admissible files, and should call mood_unload() to free the mood instance afterwards.
If the message pointer is not NULL, a suitable message is returned there in all cases. The caller must free this string.
int mood_loop | ( | struct mood_instance * | m, |
osl_rbtree_loop_func * | func, | ||
void * | data | ||
) |
Iterate over the admissible files of a mood instance.
This wrapper around score_loop() is the mood counterpart of playlist_loop().
m | Determines the score table to iterate. Must not be NULL. |
func | See score_loop(). |
data | See score_loop(). |
References score_loop().
int moods_event_handler | ( | enum afs_events | event, |
__a_unused struct para_buffer * | pb, | ||
void * | data | ||
) |
Notification callback for the moods table.
event | Type of the event just occurred. |
pb | Unused. |
data | Its type depends on the event. |
This function updates the score table according to the event that has occurred. Two actions are possible: (a) reload the current mood, or (b) add/remove/update the row of the score table which corresponds to the audio file that has been modified or whose afs info has been changed. It depends on the type of the event which action (if any) is performed.
The callbacks of command handlers such as com_add() or com_touch() which modify the audio file table call this function. The virtual streaming system also calls this after it has updated the afs info of the file it is about to stream (the one with the highest score). If the file stays admissible, its score is recomputed so that a different file is picked next time.