libextractor  1.11
About: GNU libextractor is a library used to extract meta-data from files of arbitrary type.
  Fossies Dox: libextractor-1.11.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

midi_extractor.c
Go to the documentation of this file.
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  */
34 {
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
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",
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",
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",
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",
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",
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",
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 */
@ EXTRACTOR_METAFORMAT_UTF8
Definition: extractor.h:102
#define NULL
Definition: getopt1.c:60
@ EXTRACTOR_METATYPE_COMMENT
Definition: extractor.h:131
@ EXTRACTOR_METATYPE_TITLE
Definition: extractor.h:134
@ EXTRACTOR_METATYPE_COPYRIGHT
Definition: extractor.h:183
@ EXTRACTOR_METATYPE_SOURCE_DEVICE
Definition: extractor.h:292
@ EXTRACTOR_METATYPE_MIMETYPE
Definition: extractor.h:129
@ EXTRACTOR_METATYPE_LYRICS
Definition: extractor.h:316
EventType
@ ET_SEQUENCE_NUMBER
@ ET_SEQUENCE_SPECIRFIC_EVENT
@ ET_END_OF_TRACK
@ ET_CHANNEL_PREFIX_ASSIGNMENT
@ ET_TEXT_EVENT
@ ET_TEMPO_SETTING
@ ET_INSTRUMENT_NAME
@ ET_CUE_POINT
@ ET_TIME_SIGNATURE
@ ET_LYRIC_TEXT
@ ET_SMPTE_OFFSET
@ ET_TRACK_NAME
@ ET_MARKER_TEXT
@ ET_COPYRIGHT_NOTICE
@ ET_KEY_SIGNATURE
void EXTRACTOR_midi_extract_method(struct EXTRACTOR_ExtractContext *ec)
plaform specifics
uint64_t(* get_size)(void *cls)
Definition: extractor.h:520
EXTRACTOR_MetaDataProcessor proc
Definition: extractor.h:525
ssize_t(* read)(void *cls, void **data, size_t size)
Definition: extractor.h:494