diff --git a/engine/drumkit.c b/engine/drumkit.c index 0193446c1a3322c419229cd7deac716901f72b3f..67d09364a061c80e12dfb0ea90682deca5c7d951 100644 --- a/engine/drumkit.c +++ b/engine/drumkit.c @@ -94,10 +94,9 @@ static void xpath_get_float(float *out, xmlNodePtr node, const char *xpathExpr, const char *s; s = xpath_value_as_string(node, xpathExpr, xpathCtx); - if (s == NULL) { - return; + if (s) { + *out = strtof(s, NULL); } - *out = strtof(s, NULL); } // Evaluate an XPath expression and store the result as an @@ -108,10 +107,9 @@ static void xpath_get_int(int *out, xmlNodePtr node, const char *xpathExpr, const char *s; s = xpath_value_as_string(node, xpathExpr, xpathCtx); - if (s == NULL) { - return; + if (s) { + *out = atoi(s); } - *out = atoi(s); } // Evaluate an XPath expression and store the result as a string. The @@ -120,7 +118,12 @@ static void xpath_get_int(int *out, xmlNodePtr node, const char *xpathExpr, static void xpath_get_string(char **out, xmlNodePtr node, const char *xpathExpr, xmlXPathContextPtr xpathCtx) { - *out = strdup(xpath_value_as_string(node, xpathExpr, xpathCtx)); + const char *s; + + s = xpath_value_as_string(node, xpathExpr, xpathCtx); + if (s) { + *out = strdup(s); + } } // Count the number of nodes returned by an XPath expression. @@ -300,17 +303,19 @@ static int parse_instrument(struct instrument *ins, xmlNodePtr node, layers = xmlXPathNodeEval(node, (xmlChar *)".//dk:layer", xpathCtx); if (layers == NULL || layers->nodesetval == NULL) { - printf("error: instrument has no layers?\n"); + fprintf(stderr, "warning: instrument has no layers\n"); goto fail; } ins->num_layers = layers->nodesetval->nodeNr; - ins->layers = (struct layer *)calloc(ins->num_layers, sizeof(struct layer)); - for (i = 0; i < ins->num_layers; i++) { - if (!parse_layer(&ins->layers[i], layers->nodesetval->nodeTab[i], - xpathCtx, basedir, target_samplerate)) { - printf("error parsing instrument layer %d\n", i); - goto fail; + if (ins->num_layers > 0) { + ins->layers = (struct layer *)calloc(ins->num_layers, sizeof(struct layer)); + for (i = 0; i < ins->num_layers; i++) { + if (!parse_layer(&ins->layers[i], layers->nodesetval->nodeTab[i], + xpathCtx, basedir, target_samplerate)) { + fprintf(stderr, "error parsing instrument layer %d\n", i); + goto fail; + } } } @@ -327,8 +332,10 @@ static void free_instrument(struct instrument *ins) { for (i = 0; i < ins->num_layers; i++) { free_layer(&ins->layers[i]); } - free(ins->layers); - free(ins->name); + if (ins->layers) + free(ins->layers); + if (ins->name) + free(ins->name); } // Find the instrument layer corresponding to a specific velocity. @@ -350,7 +357,6 @@ static int parse_instruments(struct instrument **instruments, int i, n; n = nodes->nodeNr; - printf("found %d instruments\n", n); *instruments = (struct instrument *)calloc(n, sizeof(struct instrument)); for (i = 0; i < n; i++) { @@ -389,7 +395,7 @@ static void fix_midi_notes(struct drumkit *kit) { // Assign default MIDI note mapping if all the notes are the same. if (note_cardinality == 1) { - printf("drumkit lacks proper MIDI note mapping, setting default assignments...\n"); + fprintf(stderr, "warning: drumkit lacks proper MIDI note mapping, setting default assignments\n"); for (i = 0; i < kit->num_instruments; i++) { kit->instruments[i].note = i + 36; } @@ -406,9 +412,12 @@ struct drumkit *drumkit_new(const char *filename, int target_samplerate) { } // Assign the Hydrogen drumkit namespace to all XML nodes in a document. +// +// BUG: this causes a memory leak of a few bytes per XML node, +// reported by the address sanitizer. static void fix_bad_xml(xmlNodePtr cur, xmlNsPtr ns) { for (; cur; cur = cur->next) { - if (cur->type == XML_ELEMENT_NODE) { + if (cur->type == XML_ELEMENT_NODE && !cur->ns) { xmlSetNs(cur, ns); } fix_bad_xml(cur->children, ns); @@ -418,6 +427,7 @@ static void fix_bad_xml(xmlNodePtr cur, xmlNsPtr ns) { int drumkit_load(struct drumkit *kit, const char *filename, int target_samplerate) { char *basedir = NULL; xmlDocPtr doc = NULL; + xmlNsPtr ns = NULL; xmlNodePtr root_element = NULL; xmlXPathContextPtr xpathCtx = NULL; xmlXPathObjectPtr xpathObj = NULL; @@ -438,7 +448,6 @@ int drumkit_load(struct drumkit *kit, const char *filename, int target_samplerat // elements. root_element = xmlDocGetRootElement(doc); if (!strcmp(root_element->name, "drumkit_info") && root_element->ns == NULL) { - xmlNsPtr ns; fprintf(stderr, "spotted old-style (bad) XML\n"); ns = xmlNewNs(root_element, (xmlChar *)"http://www.hydrogen-music.org/drumkit", (xmlChar *)""); fix_bad_xml(root_element, ns); diff --git a/engine/sampler.c b/engine/sampler.c index a11273f6749581434cb5212ee2f05a79b98ffa29..d8dccdc6c93ae852492467ac3e20b039ad565691 100644 --- a/engine/sampler.c +++ b/engine/sampler.c @@ -42,7 +42,7 @@ void sampler_noteon(struct sampler *sampler, int note, int velocity) { ins = drumkit_find_instrument_by_note(sampler->kit, note); if (!ins) { - printf("no instrument found for note %d\n", note); + fprintf(stderr, "no instrument found for note %d\n", note); return; } @@ -62,7 +62,7 @@ void sampler_noteon(struct sampler *sampler, int note, int velocity) { } } if (!voice) { - printf("all voices are busy\n"); + fprintf(stderr, "all voices are busy\n"); return; }