mood: Make "duration" a new keyword for the mood grammar.
[paraslash.git] / mp.c
diff --git a/mp.c b/mp.c
index c5702c625bf2125afd10f3dab8ce1627053ddb07..b5fa9cacaa6dcf9f3e2ef6f99fd025757f12097c 100644 (file)
--- a/mp.c
+++ b/mp.c
@@ -6,7 +6,7 @@
  * This file contains the public and the private API of the flex/bison based
  * mood parser.
  *
- * The public API (at the bottom of the file) allows to parse the same mood
+ * The public API (at the bottom of the file) allows parsing the same mood
  * definition many times in an efficient manner.
  *
  * The first function to call is \ref mp_init(), which analyzes the given mood
@@ -61,8 +61,8 @@ struct mp_context {
  *
  * This function turns a generalized C99 string literal like "xyz\n" into a C
  * string (containing the three characters 'x', 'y' and 'z', followed by a
- * newline character and the terminating zero byte). The function allows to
- * specify different quote characters so that, for example, regular expression
+ * newline character and the terminating zero byte). The function receives
+ * quote characters as an argument so that, for example, regular expression
  * patterns enclosed in '/' can be parsed as well. To parse a proper string
  * literal, one has to pass two double quotes as the second argument.
  *
@@ -389,6 +389,27 @@ MP_AFHI(frequency)
 MP_AFHI(channels)
 /** \endcond */
 
+/**
+ * Return the duration of the audio file from the afh info structure.
+ *
+ * \param ctx See \ref mp_path().
+ *
+ * The duration is computed by multiplying the number of chunks and the
+ * duration of one chunk.
+ *
+ * \return The approximate number of milliseconds.
+ */
+int64_t mp_duration(struct mp_context *ctx)
+{
+       struct timeval tmp;
+       int ret = get_afhi(ctx);
+
+       if (ret < 0)
+               return 0;
+       tv_scale(ctx->afhi.chunks_total, &ctx->afhi.chunk_tv, &tmp);
+       return tv2ms(&tmp);
+}
+
 /**
  * Define a function which extracts and returns the value of a meta tag.
  *
@@ -491,10 +512,10 @@ int mp_init(const char *definition, int nbytes, struct mp_context **result,
        struct mp_context *ctx;
        struct yy_buffer_state *buffer_state;
 
+       *result = NULL;
        if (!definition || nbytes == 0) { /* dummy mood */
                if (errmsg)
                        *errmsg = NULL;
-               *result = NULL;
                return 0;
        }
        ctx = para_calloc(sizeof(*ctx));
@@ -541,6 +562,8 @@ bool mp_eval_row(const struct osl_row *aft_row, struct mp_context *ctx)
 {
        if (!ctx) /* dummy mood */
                return true;
+       if (!ctx->ast) /* empty mood */
+               return true;
        assert(aft_row);
        ctx->aft_row = aft_row;
        ctx->have_afsi = false;