1use std::fmt;
6use std::collections::HashMap;
7use lazy_static::lazy_static;
8
9pub const INITIATOR: u8 = 0xf0;
11
12pub const TERMINATOR: u8 = 0xf7;
14
15pub const DEVELOPMENT: u8 = 0x7d;
17
18pub const NON_REAL_TIME: u8 = 0x7e;
20
21pub const REAL_TIME: u8 = 0x7f;
23
24#[derive(Debug)]
26pub enum SystemExclusiveError {
27 InvalidMessage,
28 InvalidManufacturer,
29}
30
31impl fmt::Display for SystemExclusiveError {
32 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
33 write!(f, "{}", match &self {
34 SystemExclusiveError::InvalidMessage => "Invalid System Exclusive message",
35 SystemExclusiveError::InvalidManufacturer => "Invalid manufacturer identifier"
36 })
37 }
38}
39
40#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
43pub enum Manufacturer {
44 Standard(u8),
45 Extended([u8; 3]),
46}
47
48impl Manufacturer {
49 pub fn from_bytes(data: &[u8]) -> Result<Self, SystemExclusiveError> {
51 if data.len() != 1 && data.len() != 3 {
52 return Err(SystemExclusiveError::InvalidManufacturer);
53 }
54 if data[0] == 0x00 {
55 Ok(Manufacturer::Extended([data[0], data[1], data[2]]))
56 }
57 else {
58 Ok(Manufacturer::Standard(data[0]))
59 }
60 }
61
62 pub fn new() -> Self {
64 Manufacturer::Standard(0x40)
65 }
66
67 pub fn to_bytes(&self) -> Vec<u8> {
69 match self {
70 Manufacturer::Standard(b) => vec![*b],
71 Manufacturer::Extended(bs) => vec![bs[0], bs[1], bs[2]],
72 }
73 }
74
75 pub fn to_hex(&self) -> String {
77 hex::encode(self.to_bytes()).to_uppercase()
78 }
79
80 pub fn is_development(&self) -> bool {
82 match self {
83 Manufacturer::Standard(b) => *b == DEVELOPMENT,
84 Manufacturer::Extended(_) => false
85 }
86 }
87
88 pub fn name(&self) -> String {
90 if self.is_development() {
91 return "Development / Non-commercial".to_string()
92 }
93
94 let hex_id = self.to_hex();
95 if let Some(n) = MANUFACTURER_NAMES.get(&*hex_id) {
96 n.to_string()
97 }
98 else {
99 "Unknown manufacturer".to_string()
100 }
101 }
102
103 pub fn group(&self) -> ManufacturerGroup {
105 if self.is_development() {
106 return ManufacturerGroup::Development
107 }
108
109 match self {
110 Manufacturer::Standard(b) => {
111 if (0x01..0x40).contains(b) {
112 ManufacturerGroup::NorthAmerican
113 }
114 else if (0x40..0x60).contains(b) {
115 ManufacturerGroup::Japanese
116 }
117 else {
118 ManufacturerGroup::EuropeanAndOther
119 }
120 },
121 Manufacturer::Extended(bs) => {
122 if (bs[1] & (1 << 6)) != 0 { ManufacturerGroup::Japanese
124 }
125 else if (bs[1] & (1 << 5)) != 0 { ManufacturerGroup::EuropeanAndOther
127 }
128 else {
129 ManufacturerGroup::NorthAmerican
130 }
131 }
132 }
133 }
134}
135
136impl fmt::Display for Manufacturer {
137 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
138 write!(f, "{}", self.name())
139 }
140}
141
142pub fn find_manufacturer(name: &str) -> Result<Manufacturer, SystemExclusiveError> {
144 for (key, value) in &*MANUFACTURER_NAMES {
145 if value.to_lowercase().starts_with(&name.to_lowercase()) {
146 let id_bytes = hex::decode(key).unwrap();
147 return Ok(Manufacturer::from_bytes(&id_bytes).unwrap());
148 }
149 }
150 return Err(SystemExclusiveError::InvalidManufacturer);
151}
152
153#[derive(Debug)]
155pub enum UniversalKind {
156 NonRealTime,
157 RealTime,
158}
159
160impl fmt::Display for UniversalKind {
161 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
162 let name = match self {
163 UniversalKind::NonRealTime => "Non-Real-time",
164 UniversalKind::RealTime => "Real-time",
165 };
166 write!(f, "{}", name)
167 }
168}
169
170#[derive(Debug)]
172pub enum Message {
173 Universal { kind: UniversalKind, target: u8, sub_id1: u8, sub_id2: u8, payload: Vec<u8> },
174 ManufacturerSpecific { manufacturer: Manufacturer, payload: Vec<u8> },
175}
176
177pub fn message_count(data: &Vec<u8>) -> usize {
180 data.iter().filter(|&n| *n == TERMINATOR).count()
181}
182
183pub fn split_messages(data: Vec<u8>) -> Vec<Vec<u8>> {
185 let mut parts: Vec<Vec<u8>> = Vec::new();
186 for part in data.split_inclusive(|&n| n == TERMINATOR) {
187 parts.push(part.to_vec());
188 }
189 parts
190}
191
192impl Message {
193 pub fn from_bytes(data: &[u8]) -> Result<Self, SystemExclusiveError> {
195 if data[0] != INITIATOR {
196 return Err(SystemExclusiveError::InvalidMessage);
197 }
198
199 let last_byte_index = data.len() - 1;
200 if data[last_byte_index] != TERMINATOR {
201 return Err(SystemExclusiveError::InvalidMessage);
202 }
203
204 if data.len() < 5 { return Err(SystemExclusiveError::InvalidMessage);
206 }
207
208 match data[1] {
209 DEVELOPMENT => Ok(Message::ManufacturerSpecific {
210 manufacturer: Manufacturer::Standard(data[1]),
211 payload: data[2..last_byte_index].to_vec()
212 }),
213 NON_REAL_TIME => Ok(Message::Universal {
214 kind: UniversalKind::NonRealTime,
215 target: data[2],
216 sub_id1: data[3],
217 sub_id2: data[4],
218 payload: data[5..last_byte_index].to_vec()
219 }),
220 REAL_TIME => Ok(Message::Universal {
221 kind: UniversalKind::RealTime,
222 target: data[2],
223 sub_id1: data[3],
224 sub_id2: data[4],
225 payload: data[5..last_byte_index].to_vec()
226 }),
227 0x00 => Ok(Message::ManufacturerSpecific {
228 manufacturer: Manufacturer::Extended([data[1], data[2], data[3]]),
229 payload: data[4..last_byte_index].to_vec()
230 }),
231 _ => Ok(Message::ManufacturerSpecific {
232 manufacturer: Manufacturer::Standard(data[1]),
233 payload: data[2..last_byte_index].to_vec()
234 }),
235 }
236 }
237
238 pub fn to_bytes(&self) -> Vec<u8> {
240 let mut result = Vec::<u8>::new();
241
242 match self {
243 Message::Universal { kind, target, sub_id1, sub_id2, payload } => {
244 result.push(INITIATOR);
245 result.push(match kind {
246 UniversalKind::NonRealTime => NON_REAL_TIME,
247 UniversalKind::RealTime => REAL_TIME,
248 });
249 result.push(*target);
250 result.push(*sub_id1);
251 result.push(*sub_id2);
252 result.extend(payload);
253 result.push(TERMINATOR);
254 },
255 Message::ManufacturerSpecific { manufacturer, payload } => {
256 result.push(INITIATOR);
257 result.extend(manufacturer.to_bytes());
258 result.extend(payload);
259 result.push(TERMINATOR);
260 }
261 }
262
263 result
264 }
265
266 pub fn digest(&self) -> md5::Digest {
268 md5::compute(self.to_bytes())
269 }
270}
271
272#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
274pub enum ManufacturerGroup {
275 Development,
276 NorthAmerican,
277 EuropeanAndOther,
278 Japanese,
279}
280
281impl fmt::Display for ManufacturerGroup {
282 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
283 let name = match self {
284 ManufacturerGroup::Development => "Development",
285 ManufacturerGroup::EuropeanAndOther => "European & Other",
286 ManufacturerGroup::Japanese => "Japanese",
287 ManufacturerGroup::NorthAmerican => "North American",
288 };
289 write!(f, "{}", name)
290 }
291}
292
293lazy_static! {
294 static ref MANUFACTURER_NAMES: HashMap<&'static str, &'static str> = {
295 HashMap::from([
296 ("01", "Sequential Circuits"),
297 ("02", "IDP"),
298 ("03", "Voyetra Turtle Beach, Inc."),
299 ("04", "Moog Music"),
300 ("05", "Passport Designs"),
301 ("06", "Lexicon Inc."),
302 ("07", "Kurzweil / Young Chang"),
303 ("08", "Fender"),
304 ("09", "MIDI9"),
305 ("0A", "AKG Acoustics"),
306 ("0B", "Voyce Music"),
307 ("0C", "WaveFrame (Timeline)"),
308 ("0D", "ADA Signal Processors, Inc."),
309 ("0E", "Garfield Electronics"),
310 ("0F", "Ensoniq"),
311 ("10", "Oberheim / Gibson Labs"),
312 ("11", "Apple"),
313 ("12", "Grey Matter Response"),
314 ("13", "Digidesign Inc."),
315 ("14", "Palmtree Instruments"),
316 ("15", "JLCooper Electronics"),
317 ("16", "Lowrey Organ Company"),
318 ("17", "Adams-Smith"),
319 ("18", "E-mu"),
320 ("19", "Harmony Systems"),
321 ("1A", "ART"),
322 ("1B", "Baldwin"),
323 ("1C", "Eventide"),
324 ("1D", "Inventronics"),
325 ("1E", "Key Concepts"),
326 ("1F", "Clarity"),
327 ("20", "Passac"),
328 ("21", "Proel Labs (SIEL)"),
329 ("22", "Synthaxe (UK)"),
330 ("23", "Stepp"),
331 ("24", "Hohner"),
332 ("25", "Twister"),
333 ("26", "Ketron s.r.l."),
334 ("27", "Jellinghaus MS"),
335 ("28", "Southworth Music Systems"),
336 ("29", "PPG (Germany)"),
337 ("2A", "JEN"),
338 ("2B", "Solid State Logic Organ Systems"),
339 ("2C", "Audio Veritrieb-P. Struven"),
340 ("2D", "Neve"),
341 ("2E", "Soundtracs Ltd."),
342 ("2F", "Elka"),
343 ("30", "Dynacord"),
344 ("31", "Viscount International Spa (Intercontinental Electronics)"),
345 ("32", "Drawmer"),
346 ("33", "Clavia Digital Instruments"),
347 ("34", "Audio Architecture"),
348 ("35", "Generalmusic Corp SpA"),
349 ("36", "Cheetah Marketing"),
350 ("37", "C.T.M."),
351 ("38", "Simmons UK"),
352 ("39", "Soundcraft Electronics"),
353 ("3A", "Steinberg Media Technologies GmbH"),
354 ("3B", "Wersi Gmbh"),
355 ("3C", "AVAB Niethammer AB"),
356 ("3D", "Digigram"),
357 ("3E", "Waldorf Electronics GmbH"),
358 ("3F", "Quasimidi"),
359
360 ("000001", "Time/Warner Interactive"),
361 ("000002", "Advanced Gravis Comp. Tech Ltd."),
362 ("000003", "Media Vision"),
363 ("000004", "Dornes Research Group"),
364 ("000005", "K-Muse"),
365 ("000006", "Stypher"),
366 ("000007", "Digital Music Corp."),
367 ("000008", "IOTA Systems"),
368 ("000009", "New England Digital"),
369 ("00000A", "Artisyn"),
370 ("00000B", "IVL Technologies Ltd."),
371 ("00000C", "Southern Music Systems"),
372 ("00000D", "Lake Butler Sound Company"),
373 ("00000E", "Alesis Studio Electronics"),
374 ("00000F", "Sound Creation"),
375 ("000010", "DOD Electronics Corp."),
376 ("000011", "Studer-Editech"),
377 ("000012", "Sonus"),
378 ("000013", "Temporal Acuity Products"),
379 ("000014", "Perfect Fretworks"),
380 ("000015", "KAT Inc."),
381 ("000016", "Opcode Systems"),
382 ("000017", "Rane Corporation"),
383 ("000018", "Anadi Electronique"),
384 ("000019", "KMX"),
385 ("00001A", "Allen & Heath Brenell"),
386 ("00001B", "Peavey Electronics"),
387 ("00001C", "360 Systems"),
388 ("00001D", "Spectrum Design and Development"),
389 ("00001E", "Marquis Music"),
390 ("00001F", "Zeta Systems"),
391 ("000020", "Axxes (Brian Parsonett)"),
392 ("000021", "Orban"),
393 ("000022", "Indian Valley Mfg."),
394 ("000023", "Triton"),
395 ("000024", "KTI"),
396 ("000025", "Breakway Technologies"),
397 ("000026", "Leprecon / CAE Inc."),
398 ("000027", "Harrison Systems Inc."),
399 ("000028", "Future Lab/Mark Kuo"),
400 ("000029", "Rocktron Corporation"),
401 ("00002A", "PianoDisc"),
402 ("00002B", "Cannon Research Group"),
403 ("00002C", "Reserved"),
404 ("00002D", "Rodgers Instrument LLC"),
405 ("00002E", "Blue Sky Logic"),
406 ("00002F", "Encore Electronics"),
407 ("000030", "Uptown"),
408 ("000031", "Voce"),
409 ("000032", "CTI Audio, Inc. (Musically Intel. Devs.)"),
410 ("000033", "S3 Incorporated"),
411 ("000034", "Broderbund / Red Orb"),
412 ("000035", "Allen Organ Co."),
413 ("000036", "Reserved"),
414 ("000037", "Music Quest"),
415 ("000038", "Aphex"),
416 ("000039", "Gallien Krueger"),
417 ("00003A", "IBM"),
418 ("00003B", "Mark Of The Unicorn"),
419 ("00003C", "Hotz Corporation"),
420 ("00003D", "ETA Lighting"),
421 ("00003E", "NSI Corporation"),
422 ("00003F", "Ad Lib, Inc."),
423 ("000040", "Richmond Sound Design"),
424 ("000041", "Microsoft"),
425 ("000042", "Mindscape (Software Toolworks)"),
426 ("000043", "Russ Jones Marketing / Niche"),
427 ("000044", "Intone"),
428 ("000045", "Advanced Remote Technologies"),
429 ("000046", "White Instruments"),
430 ("000047", "GT Electronics/Groove Tubes"),
431 ("000048", "Pacific Research & Engineering"),
432 ("000049", "Timeline Vista, Inc."),
433 ("00004A", "Mesa Boogie Ltd."),
434 ("00004B", "FSLI"),
435 ("00004C", "Sequoia Development Group"),
436 ("00004D", "Studio Electronics"),
437 ("00004E", "Euphonix, Inc"),
438 ("00004F", "InterMIDI, Inc."),
439 ("000050", "MIDI Solutions Inc."),
440 ("000051", "3DO Company"),
441 ("000052", "Lightwave Research / High End Systems"),
442 ("000053", "Micro-W Corporation"),
443 ("000054", "Spectral Synthesis, Inc."),
444 ("000055", "Lone Wolf"),
445 ("000056", "Studio Technologies Inc."),
446 ("000057", "Peterson Electro-Musical Product, Inc."),
447 ("000058", "Atari Corporation"),
448 ("000059", "Marion Systems Corporation"),
449 ("00005A", "Design Event"),
450 ("00005B", "Winjammer Software Ltd."),
451 ("00005C", "AT&T Bell Laboratories"),
452 ("00005D", "Reserved"),
453 ("00005E", "Symetrix"),
454 ("00005F", "MIDI the World"),
455 ("000060", "Spatializer"),
456 ("000061", "Micros ‘N MIDI"),
457 ("000062", "Accordians International"),
458 ("000063", "EuPhonics (now 3Com)"),
459 ("000064", "Musonix"),
460 ("000065", "Turtle Beach Systems (Voyetra)"),
461 ("000066", "Loud Technologies / Mackie"),
462 ("000067", "Compuserve"),
463 ("000068", "BEC Technologies"),
464 ("000069", "QRS Music Inc"),
465 ("00006A", "P.G. Music"),
466 ("00006B", "Sierra Semiconductor"),
467 ("00006C", "EpiGraf"),
468 ("00006D", "Electronics Diversified Inc"),
469 ("00006E", "Tune 1000"),
470 ("00006F", "Advanced Micro Devices"),
471 ("000070", "Mediamation"),
472 ("000071", "Sabine Musical Mfg. Co. Inc."),
473 ("000072", "Woog Labs"),
474 ("000073", "Micropolis Corp"),
475 ("000074", "Ta Horng Musical Instrument"),
476 ("000075", "e-Tek Labs (Forte Tech)"),
477 ("000076", "Electro-Voice"),
478 ("000077", "Midisoft Corporation"),
479 ("000078", "QSound Labs"),
480 ("000079", "Westrex"),
481 ("00007A", "Nvidia"),
482 ("00007B", "ESS Technology"),
483 ("00007C", "Media Trix Peripherals"),
484 ("00007D", "Brooktree Corp"),
485 ("00007E", "Otari Corp"),
486 ("00007F", "Key Electronics, Inc."),
487 ("000100", "Shure Incorporated"),
488 ("000101", "AuraSound"),
489 ("000102", "Crystal Semiconductor"),
490 ("000103", "Conexant (Rockwell)"),
491 ("000104", "Silicon Graphics"),
492 ("000105", "M-Audio (Midiman)"),
493 ("000106", "PreSonus"),
494 ("000108", "Topaz Enterprises"),
496 ("000109", "Cast Lighting"),
497 ("00010A", "Microsoft Consumer Division"),
498 ("00010B", "Sonic Foundry"),
499 ("00010C", "Line 6 (Fast Forward) (Yamaha)"),
500 ("00010D", "Beatnik Inc"),
501 ("00010E", "Van Koevering Company"),
502 ("00010F", "Altech Systems"),
503 ("000110", "S & S Research"),
504 ("000111", "VLSI Technology"),
505 ("000112", "Chromatic Research"),
506 ("000113", "Sapphire"),
507 ("000114", "IDRC"),
508 ("000115", "Justonic Tuning"),
509 ("000116", "TorComp Research Inc."),
510 ("000117", "Newtek Inc."),
511 ("000118", "Sound Sculpture"),
512 ("000119", "Walker Technical"),
513 ("00011A", "Digital Harmony (PAVO)"),
514 ("00011B", "InVision Interactive"),
515 ("00011C", "T-Square Design"),
516 ("00011D", "Nemesys Music Technology"),
517 ("00011E", "DBX Professional (Harman Intl)"),
518 ("00011F", "Syndyne Corporation"),
519 ("000120", "Bitheadz"),
520 ("000121", "BandLab Technologies"),
521 ("000122", "Analog Devices"),
522 ("000123", "National Semiconductor"),
523 ("000124", "Boom Theory / Adinolfi Alternative Percussion"),
524 ("000125", "Virtual DSP Corporation"),
525 ("000126", "Antares Systems"),
526 ("000127", "Angel Software"),
527 ("000128", "St Louis Music"),
528 ("000129", "Passport Music Software LLC (Gvox)"),
529 ("00012A", "Ashley Audio Inc."),
530 ("00012B", "Vari-Lite Inc."),
531 ("00012C", "Summit Audio Inc."),
532 ("00012D", "Aureal Semiconductor Inc."),
533 ("00012E", "SeaSound LLC"),
534 ("00012F", "U.S. Robotics"),
535 ("000130", "Aurisis Research"),
536 ("000131", "Nearfield Research"),
537 ("000132", "FM7 Inc"),
538 ("000133", "Swivel Systems"),
539 ("000134", "Hyperactive Audio Systems"),
540 ("000135", "MidiLite (Castle Studios Productions)"),
541 ("000136", "Radikal Technologies"),
542 ("000137", "Roger Linn Design"),
543 ("000138", "TC-Helicon Vocal Technologies"),
544 ("000139", "Event Electronics"),
545 ("00013A", "Sonic Network Inc"),
546 ("00013B", "Realtime Music Solutions"),
547 ("00013C", "Apogee Digital"),
548 ("00013D", "Classical Organs, Inc."),
549 ("00013E", "Microtools Inc."),
550 ("00013F", "Numark Industries"),
551 ("000140", "Frontier Design Group, LLC"),
552 ("000141", "Recordare LLC"),
553 ("000142", "Starr Labs"),
554 ("000143", "Voyager Sound Inc."),
555 ("000144", "Manifold Labs"),
556 ("000145", "Aviom Inc."),
557 ("000146", "Mixmeister Technology"),
558 ("000147", "Notation Software"),
559 ("000148", "Mercurial Communications"),
560 ("000149", "Wave Arts"),
561 ("00014A", "Logic Sequencing Devices"),
562 ("00014B", "Axess Electronics"),
563 ("00014C", "Muse Research"),
564 ("00014D", "Open Labs"),
565 ("00014E", "Guillemot Corp"),
566 ("00014F", "Samson Technologies"),
567 ("000150", "Electronic Theatre Controls"),
568 ("000151", "Blackberry (RIM)"),
569 ("000152", "Mobileer"),
570 ("000153", "Synthogy"),
571 ("000154", "Lynx Studio Technology Inc."),
572 ("000155", "Damage Control Engineering LLC"),
573 ("000156", "Yost Engineering, Inc."),
574 ("000157", "Brooks & Forsman Designs LLC / DrumLite"),
575 ("000158", "Infinite Response"),
576 ("000159", "Garritan Corp"),
577 ("00015A", "Plogue Art et Technologie, Inc"),
578 ("00015B", "RJM Music Technology"),
579 ("00015C", "Custom Solutions Software"),
580 ("00015D", "Sonarcana LLC / Highly Liquid"),
581 ("00015E", "Centrance"),
582 ("00015F", "Kesumo LLC"),
583 ("000160", "Stanton (Gibson Brands)"),
584 ("000161", "Livid Instruments"),
585 ("000162", "First Act / 745 Media"),
586 ("000163", "Pygraphics, Inc."),
587 ("000164", "Panadigm Innovations Ltd"),
588 ("000165", "Avedis Zildjian Co"),
589 ("000166", "Auvital Music Corp"),
590 ("000167", "You Rock Guitar (was: Inspired Instruments)"),
591 ("000168", "Chris Grigg Designs"),
592 ("000169", "Slate Digital LLC"),
593 ("00016A", "Mixware"),
594 ("00016B", "Social Entropy"),
595 ("00016C", "Source Audio LLC"),
596 ("00016D", "Ernie Ball / Music Man"),
597 ("00016E", "Fishman"),
598 ("00016F", "Custom Audio Electronics"),
599 ("000170", "American Audio/DJ"),
600 ("000171", "Mega Control Systems"),
601 ("000172", "Kilpatrick Audio"),
602 ("000173", "iConnectivity"),
603 ("000174", "Fractal Audio"),
604 ("000175", "NetLogic Microsystems"),
605 ("000176", "Music Computing"),
606 ("000177", "Nektar Technology Inc"),
607 ("000178", "Zenph Sound Innovations"),
608 ("000179", "DJTechTools.com"),
609 ("00017A", "Rezonance Labs"),
610 ("00017B", "Decibel Eleven"),
611 ("00017C", "CNMAT"),
612 ("00017D", "Media Overkill"),
613 ("00017E", "Confusion Studios"),
614 ("00017F", "moForte Inc"),
615 ("000200", "Miselu Inc"),
616 ("000201", "Amelia's Compass LLC"),
617 ("000202", "Zivix LLC"),
618 ("000203", "Artiphon"),
619 ("000204", "Synclavier Digital"),
620 ("000205", "Light & Sound Control Devices LLC"),
621 ("000206", "Retronyms Inc"),
622 ("000207", "JS Technologies"),
623 ("000208", "Quicco Sound"),
624 ("000209", "A-Designs Audio"),
625 ("00020A", "McCarthy Music Corp"),
626 ("00020B", "Denon DJ"),
627 ("00020C", "Keith Robert Murray"),
628 ("00020D", "Google"),
629 ("00020E", "ISP Technologies"),
630 ("00020F", "Abstrakt Instruments LLC"),
631 ("000210", "Meris LLC"),
632 ("000211", "Sensorpoint LLC"),
633 ("000212", "Hi-Z Labs"),
634 ("000213", "Imitone"),
635 ("000214", "Intellijel Designs Inc."),
636 ("000215", "Dasz Instruments Inc."),
637 ("000216", "Remidi"),
638 ("000217", "Disaster Area Designs LLC"),
639 ("000218", "Universal Audio"),
640 ("000219", "Carter Duncan Corp"),
641 ("00021A", "Essential Technology"),
642 ("00021B", "Cantux Research LLC"),
643 ("00021C", "Hummel Technologies"),
644 ("00021D", "Sensel Inc"),
645 ("00021E", "DBML Group"),
646 ("00021F", "Madrona Labs"),
647 ("000220", "Mesa Boogie"),
648 ("000221", "Effigy Labs"),
649 ("000222", "Amenote"),
650 ("000223", "Red Panda LLC"),
651 ("000224", "OnSong LLC"),
652 ("000225", "Jamboxx Inc."),
653 ("000226", "Electro-Harmonix"),
654 ("000227", "RnD64 Inc"),
655 ("000228", "Neunaber Technology LLC"),
656 ("000229", "Kaom Inc."),
657 ("00022A", "Hallowell EMC"),
658 ("00022B", "Sound Devices, LLC"),
659 ("00022C", "Spectrasonics, Inc"),
660 ("00022D", "Second Sound, LLC"),
661 ("00022E", "8eo (Horn)"),
662 ("00022F", "VIDVOX LLC"),
663 ("000230", "Matthews Effects"),
664 ("000231", "Bright Blue Beetle"),
665 ("000232", "Audio Impressions"),
666 ("000233", " Looperlative"),
667 ("000234", "Steinway"),
668 ("000235", "Ingenious Arts and Technologies LLC"),
669 ("000236", "DCA Audio"),
670 ("000237", "Buchla USA"),
671 ("000238", "Sinicon"),
672 ("000239", "Isla Instruments"),
673 ("00023A", "Soundiron LLC"),
674 ("00023B", "Sonoclast, LLC"),
675 ("00023C", "Copper and Cedar"),
676 ("00023D", "Whirled Notes"),
677 ("00023E", "Cejetvole, LLC"),
678 ("00023F", "DAWn Audio LLC"),
679 ("000240", "Space Brain Circuits"),
680 ("000241", "Caedence"),
681 ("000242", "HCN Designs, LLC (The MIDI Maker)"),
682 ("000243", "PTZOptics"),
683 ("000244", "Noise Engineering"),
684 ("000245", "Synthesia LLC"),
685 ("000246", "Jeff Whitehead Lutherie LLC"),
686 ("000247", "Wampler Pedals Inc."),
687 ("000248", "Tapis Magique"),
688 ("000249", "Leaf Secrets"),
689 ("00024A", "Groove Synthesis"),
690 ("00024B", "Audiocipher Technologies LLC"),
691 ("00024C", "Mellotron Inc."),
692 ("00024D", "Hologram Electronics LLC"),
693 ("00024E", "iCON Americas, LLC"),
694 ("00024F", "Singular Sound"),
695 ("000250", "Genovation Inc"),
696 ("000251", "Method Red"),
697 ("000252", "Brain Inventions"),
698 ("000253", "Synervoz Communications Inc."),
699 ("000254", "Hypertriangle Inc"),
700
701 ("002000", "Dream SAS"),
703 ("002001", "Strand Lighting"),
704 ("002002", "Amek Div of Harman Industries"),
705 ("002003", "Casa Di Risparmio Di Loreto"),
706 ("002004", "Böhm electronic GmbH"),
707 ("002005", "Syntec Digital Audio"),
708 ("002006", "Trident Audio Developments"),
709 ("002007", "Real World Studio"),
710 ("002008", "Evolution Synthesis, Ltd"),
711 ("002009", "Yes Technology"),
712 ("00200A", "Audiomatica"),
713 ("00200B", "Bontempi SpA (Sigma)"),
714 ("00200C", "F.B.T. Elettronica SpA"),
715 ("00200D", "MidiTemp GmbH"),
716 ("00200E", "LA Audio (Larking Audio)"),
717 ("00200F", "Zero 88 Lighting Limited"),
718 ("002010", "Micon Audio Electronics GmbH"),
719 ("002011", "Forefront Technology"),
720 ("002012", "Studio Audio and Video Ltd."),
721 ("002013", "Kenton Electronics"),
722 ("002014", "Celco/ Electrosonic"),
723 ("002015", "ADB"),
724 ("002016", "Marshall Products Limited"),
725 ("002017", "DDA"),
726 ("002018", "BSS Audio Ltd."),
727 ("002019", "MA Lighting Technology"),
728 ("00201A", "Fatar SRL c/o Music Industries"),
729 ("00201B", "QSC Audio Products Inc."),
730 ("00201C", "Artisan Clasic Organ Inc."),
731 ("00201D", "Orla Spa"),
732 ("00201E", "Pinnacle Audio (Klark Teknik PLC)"),
733 ("00201F", "TC Electronics"),
734 ("002020", "Doepfer Musikelektronik GmbH"),
735 ("002021", "Creative ATC / E-mu"),
736 ("002022", "Seyddo/Minami"),
737 ("002023", "LG Electronics (Goldstar)"),
738 ("002024", "Midisoft sas di M.Cima & C"),
739 ("002025", "Samick Musical Inst. Co. Ltd."),
740 ("002026", "Penny and Giles (Bowthorpe PLC)"),
741 ("002027", "Acorn Computer"),
742 ("002028", "LSC Electronics Pty. Ltd."),
743 ("002029", "Focusrite/Novation"),
744 ("00202A", "Samkyung Mechatronics"),
745 ("00202B", "Medeli Electronics Co."),
746 ("00202C", "Charlie Lab SRL"),
747 ("00202D", "Blue Chip Music Technology"),
748 ("00202E", "BEE OH Corp"),
749 ("00202F", "LG Semicon America"),
750 ("002030", "TESI"),
751 ("002031", "EMAGIC"),
752 ("002032", "Behringer GmbH"),
753 ("002033", "Access Music Electronics"),
754 ("002034", "Synoptic"),
755 ("002035", "Hanmesoft"),
756 ("002036", "Terratec Electronic GmbH"),
757 ("002037", "Proel SpA"),
758 ("002038", "IBK MIDI"),
759 ("002039", "IRCAM"),
760 ("00203A", "Propellerhead Software"),
761 ("00203B", "Red Sound Systems Ltd"),
762 ("00203C", "Elektron ESI AB"),
763 ("00203D", "Sintefex Audio"),
764 ("00203E", "MAM (Music and More)"),
765 ("00203F", "Amsaro GmbH"),
766 ("002040", "CDS Advanced Technology BV (Lanbox)"),
767 ("002041", "Mode Machines (Touched By Sound GmbH)"),
768 ("002042", "DSP Arts"),
769 ("002043", "Phil Rees Music Tech"),
770 ("002044", "Stamer Musikanlagen GmbH"),
771 ("002045", "Musical Muntaner S.A. dba Soundart"),
772 ("002046", "C-Mexx Software"),
773
774 ("00206B", "Arturia"),
775 ("002076", "Teenage Engineering"),
776
777 ("002103", "PreSonus Software Ltd"),
778
779 ("002109", "Native Instruments"),
780
781 ("002110", "ROLI Ltd"),
782
783 ("00211A", "IK Multimedia"),
784
785 ("00211D", "Ableton"),
786
787 ("40", "Kawai Musical Instruments MFG. CO. Ltd"),
788 ("41", "Roland Corporation"),
789 ("42", "Korg Inc."),
790 ("43", "Yamaha"),
791 ("44", "Casio Computer Co. Ltd"),
792 ("46", "Kamiya Studio Co. Ltd"),
794 ("47", "Akai Electric Co. Ltd."),
795 ("48", "Victor Company of Japan, Ltd."),
796 ("4B", "Fujitsu Limited"),
797 ("4C", "Sony Corporation"),
798 ("4E", "Teac Corporation"),
799 ("50", "Matsushita Electric Industrial Co. , Ltd"),
800 ("51", "Fostex Corporation"),
801 ("52", "Zoom Corporation"),
802 ("54", "Matsushita Communication Industrial Co., Ltd."),
803 ("55", "Suzuki Musical Instruments MFG. Co., Ltd."),
804 ("56", "Fuji Sound Corporation Ltd."),
805 ("57", "Acoustic Technical Laboratory, Inc."),
806 ("59", "Faith, Inc."),
808 ("5A", "Internet Corporation"),
809 ("5C", "Seekers Co. Ltd."),
811 ("5F", "SD Card Association"),
813
814 ("004000", "Crimson Technology Inc."),
815 ("004001", "Softbank Mobile Corp"),
816 ("004003", "D&M Holdings Inc."),
817 ("004004", "Xing Inc."),
818 ("004005", "Alpha Theta Corporation"),
819 ("004006", "Pioneer Corporation"),
820 ("004007", "Slik Corporation"),
821 ])
822 };
823}
824
825#[cfg(test)]
826mod tests {
827 use super::*;
828
829 #[test]
830 fn new_message_manufacturer_standard() {
831 let data = vec![0xF0, 0x40, 0x00, 0x20, 0x00, 0x04, 0x00, 0x3F, 0xF7];
832 let message = Message::from_bytes(&data);
833 if let Ok(Message::ManufacturerSpecific { manufacturer, .. }) = message {
834 assert_eq!(manufacturer, Manufacturer::Standard(0x40));
835 }
836 else {
837 panic!("Expected a manufacturer-specific message with standard identifier");
838 }
839 }
840
841 #[test]
842 fn new_message_manufacturer_extended() {
843 let data = vec![0xF0, 0x00, 0x00, 0x0E, 0x00, 0x41, 0x63, 0x00, 0x5D, 0xF7];
844 let message = Message::from_bytes(&data);
845 if let Ok(Message::ManufacturerSpecific { manufacturer, .. }) = message {
846 assert_eq!(manufacturer, Manufacturer::Extended([0x00, 0x00, 0x0E]));
847 }
848 else {
849 panic!("Expected a manufacturer-specific message with extended identifier");
850 }
851 }
852
853 #[test]
854 fn manufacturer_message() {
855 let message = Message::ManufacturerSpecific {
856 manufacturer: Manufacturer::Standard(0x40), payload: vec![
858 0x00, 0x20, 0x00, 0x04, 0x00, 0x3F, ],
865 };
866 let message_bytes = message.to_bytes();
867 assert_eq!(message_bytes, vec![0xF0, 0x40, 0x00, 0x20, 0x00, 0x04, 0x00, 0x3F, 0xF7]);
868 }
869
870 #[test]
871 fn standard_manufacturer() {
872 let message = Message::ManufacturerSpecific {
873 manufacturer: Manufacturer::Standard(0x43),
874 payload: vec![],
875 };
876 let message_bytes = message.to_bytes();
877 assert_eq!(message_bytes, vec![0xF0, 0x43, 0xF7]);
878 }
879
880 #[test]
881 fn extended_manufacturer() {
882 let message = Message::ManufacturerSpecific {
883 manufacturer: Manufacturer::Extended([0x00, 0x00, 0x01]),
884 payload: vec![],
885 };
886 let message_bytes = message.to_bytes();
887 assert_eq!(message_bytes, vec![0xF0, 0x00, 0x00, 0x01, 0xF7]);
888 }
889
890 #[test]
891 fn universal() {
892 let message = Message::Universal {
893 kind: UniversalKind::NonRealTime,
894 target: 0x00,
895 sub_id1: 0x06, sub_id2: 0x01, payload: vec![]
898 };
899 let message_bytes = message.to_bytes();
900 assert_eq!(message_bytes, vec![INITIATOR, NON_REAL_TIME, 0x00, 0x06, 0x01, TERMINATOR]);
901 }
902
903 #[test]
904 fn development_manufacturer() {
905 let message = Message::ManufacturerSpecific {
906 manufacturer: Manufacturer::Standard(DEVELOPMENT),
907 payload: vec![],
908 };
909 let message_bytes = message.to_bytes();
910 assert_eq!(message_bytes, vec![INITIATOR, DEVELOPMENT, TERMINATOR]);
911 }
912
913 #[test]
914 fn manufacturer_display_name() {
915 let manufacturer = Manufacturer::Standard(0x43);
916 assert_eq!(format!("{}", manufacturer), "Yamaha");
917 }
918
919 #[test]
920 fn find_manufacturer_name_success() {
921 let manuf = find_manufacturer("yama").unwrap();
922 assert_eq!(manuf.name(), "Yamaha");
923 }
924
925 #[test]
926 fn find_manufacturer_name_failure() {
927 assert!(find_manufacturer("humppaurku").is_err());
928 }
929}