Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/third_party/pipewire/spa/control/   (Firefox Browser Version 153.0.1©)  Datei vom 27.6.2026 mit Größe 4 kB image not shown  

Quelle  ump-utils.h

  Sprache: C
 

/* Simple Plugin API */
/* SPDX-FileCopyrightText: Copyright © 2024 Wim Taymans */
/* SPDX-License-Identifier: MIT */


#ifndef SPA_CONTROL_UMP_UTILS_H
#define SPA_CONTROL_UMP_UTILS_H

#ifdef __cplusplus
extern "C" {
#endif

#include <errno.h>
#include <spa/utils/defs.h>

#ifndef SPA_API_CONTROL_UMP_UTILS
 #ifdef SPA_API_IMPL
  #define SPA_API_CONTROL_UMP_UTILS SPA_API_IMPL
 #else
  #define SPA_API_CONTROL_UMP_UTILS static inline
 #endif
#endif
/**
 * \addtogroup spa_control
 * \{
 */


SPA_API_CONTROL_UMP_UTILS size_t spa_ump_message_size(uint8_t message_type)
{
 static const uint32_t ump_sizes[] = {
  [0x0] = 1/* Utility messages */
  [0x1] = 1/* System messages */
  [0x2] = 1/* MIDI 1.0 messages */
  [0x3] = 2/* 7bit SysEx messages */
  [0x4] = 2/* MIDI 2.0 messages */
  [0x5] = 4/* 8bit data message */
  [0x6] = 1,
  [0x7] = 1,
  [0x8] = 2,
  [0x9] = 2,
  [0xa] = 2,
  [0xb] = 3,
  [0xc] = 3,
  [0xd] = 4/* Flexible data messages */
  [0xe] = 4,
  [0xf] = 4/* Stream messages */
 };
 return ump_sizes[message_type & 0xf];
}

SPA_API_CONTROL_UMP_UTILS int spa_ump_to_midi(uint32_t *ump, size_t ump_size,
  uint8_t *midi, size_t midi_maxsize)
{
 int size = 0;

 if (ump_size < 4)
  return 0;
 if (midi_maxsize < 8)
  return -ENOSPC;

 switch (ump[0] >> 28) {
 case 0x1: /* System Real Time and System Common Messages (except System Exclusive) */
  midi[size++] = (ump[0] >> 16) & 0xff;
  if (midi[0] >= 0xf1 && midi[0] <= 0xf3) {
   midi[size++] = (ump[0] >> 8) & 0x7f;
   if (midi[0] == 0xf2)
    midi[size++] = ump[0] & 0x7f;
  }
  break;
 case 0x2: /* MIDI 1.0 Channel Voice Messages */
  midi[size++] = (ump[0] >> 16);
  midi[size++] = (ump[0] >> 8);
  if (midi[0] < 0xc0 || midi[0] > 0xdf)
   midi[size++] = (ump[0]);
  break;
 case 0x3: /* Data Messages (including System Exclusive) */
 {
  uint8_t status, i, bytes;

  if (ump_size < 8)
   return 0;

  status = (ump[0] >> 20) & 0xf;
  bytes = SPA_CLAMP((ump[0] >> 16) & 0xf, 0u, 6u);

  if (status == 0 || status == 1)
   midi[size++] = 0xf0;
  for (i = 0 ; i < bytes; i++)
   /* ump[0] >> 8 | ump[0] | ump[1] >> 24 | ump[1] >>16 ... */
   midi[size++] = ump[(i+2)/4] >> ((5-i)%4 * 8);
  if (status == 0 || status == 3)
   midi[size++] = 0xf7;
  break;
 }
 case 0x4: /* MIDI 2.0 Channel Voice Messages */
  if (ump_size < 8)
   return 0;
  midi[size++] = (ump[0] >> 16) | 0x80;
  if (midi[0] < 0xc0 || midi[0] > 0xdf)
   midi[size++] = (ump[0] >> 8) & 0x7f;
  midi[size++] = (ump[1] >> 25);
  break;

 case 0x0: /* Utility Messages */
 case 0x5: /* Data Messages */
 default:
  return 0;
 }
 return size;
}

SPA_API_CONTROL_UMP_UTILS int spa_ump_from_midi(uint8_t **midi, size_t *midi_size,
  uint32_t *ump, size_t ump_maxsize, uint8_t group, uint64_t *state)
{
 int size = 0;
 uint32_t i, prefix = group << 24, to_consume = 0, bytes;
 uint8_t status, *m = (*midi), end;

 if (*midi_size < 1)
  return 0;
 if (ump_maxsize < 16)
  return -ENOSPC;

 status = m[0];

 /* SysEx */
 if (*state == 0) {
  if (status == 0xf0)
   *state = 1/* sysex start */
  else if (status == 0xf7)
   *state = 2/* sysex continue */
 }
 if (*state & 3) {
  prefix |= 0x30000000;
  if (status & 0x80) {
   m++;
   to_consume++;
  }
  bytes = SPA_CLAMP(*midi_size - to_consume, 0u, 7u);
  if (bytes > 0) {
   end = m[bytes-1];
   if (end & 0x80) {
    bytes--; /* skip terminator */
    to_consume++;
   }
   else
    end = 0xf0; /* pretend there is a continue terminator */

   bytes = SPA_CLAMP(bytes, 0u, 6u);
   to_consume += bytes;

   if (end == 0xf7) {
    if (*state == 2) {
     /* continue and done */
     prefix |= 0x3 << 20;
     *state = 0;
    }
   } else if (*state == 1) {
    /* first packet but not finished */
    prefix |= 0x1 << 20;
    *state = 2/* sysex continue */
   } else {
    /* continue and not finished */
    prefix |= 0x2 << 20;
   }
   ump[size++] = prefix | bytes << 16;
   ump[size++] = 0;
   for (i = 0 ; i < bytes; i++)
    /* ump[0] |= (m[0] & 0x7f) << 8
     * ump[0] |= (m[1] & 0x7f)
     * ump[1] |= (m[2] & 0x7f) << 24
 * ... */

    ump[(i+2)/4] |= (m[i] & 0x7f) << ((5-i)%4 * 8);
  }
 } else {
  /* regular messages */
  switch (status) {
  case 0x80 ... 0x8f:
  case 0x90 ... 0x9f:
  case 0xa0 ... 0xaf:
  case 0xb0 ... 0xbf:
  case 0xe0 ... 0xef:
   to_consume = 3;
   prefix |= 0x20000000;
   break;
  case 0xc0 ... 0xdf:
   to_consume = 2;
   prefix |= 0x20000000;
   break;
  case 0xf2:
   to_consume = 3;
   prefix = 0x10000000;
   break;
  case 0xf1: case 0xf3:
   to_consume = 2;
   prefix = 0x10000000;
   break;
  case 0xf4 ... 0xff:
   to_consume = 1;
   prefix = 0x10000000;
   break;
  default:
   return -EIO;
  }
  if (*midi_size < to_consume) {
   to_consume = *midi_size;
  } else {
   prefix |= status << 16;
   if (to_consume > 1)
    prefix |= (m[1] & 0x7f) << 8;
   if (to_consume > 2)
    prefix |= (m[2] & 0x7f);
   ump[size++] = prefix;
  }
 }
 (*midi_size) -= to_consume;
 (*midi) += to_consume;

 return size * 4;
}

/**
 * \}
 */


#ifdef __cplusplus
}  /* extern "C" */
#endif

#endif /* SPA_CONTROL_UMP_UTILS_H */

Messung V0.5 in Prozent
C=86 H=96 G=90

¤ Dauer der Verarbeitung: 0.13 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.