"Fossies" - the Fresh Open Source Software Archive

Member "libextractor-1.11/src/plugins/midi_extractor.c" (30 Jan 2021, 5378 Bytes) of package /linux/privat/libextractor-1.11.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "midi_extractor.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2      This file is part of libextractor.
    3      Copyright (C) 2012 Christian Grothoff
    4 
    5      libextractor is free software; you can redistribute it and/or modify
    6      it under the terms of the GNU General Public License as published
    7      by the Free Software Foundation; either version 3, or (at your
    8      option) any later version.
    9 
   10      libextractor is distributed in the hope that it will be useful, but
   11      WITHOUT ANY WARRANTY; without even the implied warranty of
   12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   13      General Public License for more details.
   14 
   15      You should have received a copy of the GNU General Public License
   16      along with libextractor; see the file COPYING.  If not, write to the
   17      Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   18      Boston, MA 02110-1301, USA.
   19  */
   20 /**
   21  * @file plugins/midi_extractor.c
   22  * @brief plugin to support MIDI files
   23  * @author Christian Grothoff
   24  */
   25 #include "platform.h"
   26 #include "extractor.h"
   27 #include <smf.h>
   28 
   29 
   30 /**
   31  * Types of events in MIDI.
   32  */
   33 enum EventType
   34 {
   35   ET_SEQUENCE_NUMBER = 0,
   36   ET_TEXT_EVENT = 1,
   37   ET_COPYRIGHT_NOTICE = 2,
   38   ET_TRACK_NAME = 3,
   39   ET_INSTRUMENT_NAME = 4,
   40   ET_LYRIC_TEXT = 5,
   41   ET_MARKER_TEXT = 6,
   42   ET_CUE_POINT = 7,
   43   ET_CHANNEL_PREFIX_ASSIGNMENT = 0x20,
   44   ET_END_OF_TRACK = 0x2F,
   45   ET_TEMPO_SETTING = 0x51,
   46   ET_SMPTE_OFFSET = 0x54,
   47   ET_TIME_SIGNATURE = 0x58,
   48   ET_KEY_SIGNATURE = 0x59,
   49   ET_SEQUENCE_SPECIRFIC_EVENT = 0x7F
   50 };
   51 
   52 
   53 /**
   54  * Main entry method for the 'audio/midi' extraction plugin.
   55  *
   56  * @param ec extraction context provided to the plugin
   57  */
   58 void
   59 EXTRACTOR_midi_extract_method (struct EXTRACTOR_ExtractContext *ec)
   60 {
   61   void *buf;
   62   unsigned char *data;
   63   uint64_t size;
   64   uint64_t off;
   65   ssize_t iret;
   66   smf_t *m = NULL;
   67   smf_event_t *event;
   68   uint8_t len;
   69 
   70   if (4 >= (iret = ec->read (ec->cls, &buf, 1024)))
   71     return;
   72   data = buf;
   73   if ( (data[0] != 0x4D) || (data[1] != 0x54) ||
   74        (data[2] != 0x68) || (data[3] != 0x64) )
   75     return;                /* cannot be MIDI */
   76   size = ec->get_size (ec->cls);
   77   if (size > 16 * 1024 * 1024)
   78     return; /* too large */
   79   if (NULL == (data = malloc ((size_t) size)))
   80     return; /* out of memory */
   81   memcpy (data, buf, iret);
   82   off = iret;
   83   while (off < size)
   84   {
   85     if (0 >= (iret = ec->read (ec->cls, &buf, 16 * 1024)))
   86     {
   87       free (data);
   88       return;
   89     }
   90     memcpy (&data[off], buf, iret);
   91     off += iret;
   92   }
   93   if (0 != ec->proc (ec->cls,
   94                      "midi",
   95                      EXTRACTOR_METATYPE_MIMETYPE,
   96                      EXTRACTOR_METAFORMAT_UTF8,
   97                      "text/plain",
   98                      "audio/midi",
   99                      strlen ("audio/midi") + 1))
  100     goto CLEANUP;
  101   if (NULL == (m = smf_load_from_memory (data, size)))
  102     goto CLEANUP;
  103   while (NULL != (event = smf_get_next_event (m)))
  104   {
  105     if (! smf_event_is_metadata (event))
  106       break;
  107     len = event->midi_buffer[2];
  108     if ( (len > 0) &&
  109          isspace (event->midi_buffer[2 + len]))
  110       len--;
  111 #if 0
  112     fprintf (stderr,
  113              "type: %d, len: %d value: %.*s\n",
  114              event->midi_buffer[1],
  115              event->midi_buffer[2],
  116              (int) event->midi_buffer_length - 3,
  117              (char *) &event->midi_buffer[3]);
  118 #endif
  119     if (1 != event->track_number)
  120       continue; /* heuristic to not get instruments */
  121     if (0 == len)
  122       continue;
  123     switch (event->midi_buffer[1])
  124     {
  125     case ET_TEXT_EVENT:
  126       if (0 != ec->proc (ec->cls,
  127                          "midi",
  128                          EXTRACTOR_METATYPE_COMMENT,
  129                          EXTRACTOR_METAFORMAT_UTF8,
  130                          "text/plain",
  131                          (void*) &event->midi_buffer[3],
  132                          len))
  133         goto CLEANUP;
  134       break;
  135     case ET_COPYRIGHT_NOTICE:
  136       if (0 != ec->proc (ec->cls,
  137                          "midi",
  138                          EXTRACTOR_METATYPE_COPYRIGHT,
  139                          EXTRACTOR_METAFORMAT_UTF8,
  140                          "text/plain",
  141                          (void*) &event->midi_buffer[3],
  142                          len))
  143         goto CLEANUP;
  144       break;
  145     case ET_TRACK_NAME:
  146       if (0 != ec->proc (ec->cls,
  147                          "midi",
  148                          EXTRACTOR_METATYPE_TITLE,
  149                          EXTRACTOR_METAFORMAT_UTF8,
  150                          "text/plain",
  151                          (void*) &event->midi_buffer[3],
  152                          len))
  153         goto CLEANUP;
  154       break;
  155     case ET_INSTRUMENT_NAME:
  156       if (0 != ec->proc (ec->cls,
  157                          "midi",
  158                          EXTRACTOR_METATYPE_SOURCE_DEVICE,
  159                          EXTRACTOR_METAFORMAT_UTF8,
  160                          "text/plain",
  161                          (void*) &event->midi_buffer[3],
  162                          len))
  163         goto CLEANUP;
  164       break;
  165     case ET_LYRIC_TEXT:
  166       if (0 != ec->proc (ec->cls,
  167                          "midi",
  168                          EXTRACTOR_METATYPE_LYRICS,
  169                          EXTRACTOR_METAFORMAT_UTF8,
  170                          "text/plain",
  171                          (void*) &event->midi_buffer[3],
  172                          len))
  173         goto CLEANUP;
  174       break;
  175     default:
  176       break;
  177     }
  178   }
  179 
  180 CLEANUP:
  181   if (NULL != m)
  182     smf_delete (m);
  183   free (data);
  184 }
  185 
  186 
  187 /* end of midi_extractor.c */