Donnerstag, 7. Dezember 2017

MIDI Programming for LINUX Chapter-1

MIDI Programming  SourceCode for LINUX
Author D. Selzer-McKenzie
or MIDI-Output:
//
// Programmer:    Dr.D.Selzer-McKenzie
// Creation Date: Mon Dec 21 18:00:42 PST 1998
// Last Modified: Mon Dec 21 18:00:42 PST 1998
/ Filename:      ...linuxmidi/output/method1.c
// Syntax:        C
// $Smake:        gcc -O -o %b %f && strip %b
//
#include
#include
#include
#include

int main(void) {
   char* device =  "/dev/midi" ;
   unsigned char data[3] = {0x90, 60, 127};
   // step 1: open the OSS device for writing
   int fd = open(device, O_WRONLY, 0);
   if (fd < 0) {
      printf("Error: cannot open %s\n", device);
      exit(1);
   }
   // step 2: write the MIDI information to the OSS device
   write(fd, data, sizeof(data));
   // step 3: (optional) close the OSS device
   close(fd);
   return 0;
}

#######################################
 // Syntax:        C
// $Smake:        gcc -O3 -Wall -o %b %f && strip %b
//
#include
#include
#include
#include
#include


// global variables:
int         seqfd = -1;               // sequencer file descriptor
const char* dev = "/dev/sequencer";   // name of sequencer device
int         status;                   // for error checking
int         device = 0;               // for selecting which MIDI output to use

// function declarations:
void playnotes(void);

int main(int argc, char** argv) {
   int numMidi = 0;                   // number of available MIDI outputs
   seqfd = open(dev, O_WRONLY, 0);
   if (seqfd < 0) {
      printf("Error: cannot open %s\n", dev);
      exit(1);
   }
   if (argc >= 2) {
      device = argv[1][0] - '0';
   }
   status = ioctl(seqfd, SNDCTL_SEQ_NRMIDIS, &numMidi);
   if (status != 0) {
      printf("Error: cannot access MIDI devices on soundcard\n");
      exit(1);
   }
   printf("\nThere are: %d MIDI output devices available\n", numMidi);
   if (device >= numMidi) {
      printf("You specified an invalid MIDI device\n");
      exit(1);
   }
   playnotes();
   close(seqfd);
   return 0;
}

void playnotes(void) {
   int userInput = 0;
   unsigned char outpacket[12];
   outpacket[0] = SEQ_MIDIPUTC;
   outpacket[1] = 0x90;              // note-on command
   outpacket[2] = device;
   outpacket[3] = 0;
   outpacket[4] = SEQ_MIDIPUTC;
   // outpacket[5] will be the keynumber
   outpacket[6] = device;
   outpacket[7] = 0;
   outpacket[8] = SEQ_MIDIPUTC;
   outpacket[9] = 127;              // attack velocity
   outpacket[10] = device;
   outpacket[11] = 0;
   printf("Device set to: %d\n", device);
   printf("Enter a key number larger than 127 to exit\n");
   while (userInput < 128) {
      printf("Enter note number to send out MIDI port: ");
      scanf("%d",&userInput);
      if (userInput < 128 && userInput >= 0) {
         outpacket[5] = userInput;
         write(seqfd, outpacket, 12);
      }
   }
}

####################################################
// Syntax:        C
// $Smake:        gcc -O3 -Wall -o %b %f && strip %b
//
// Description:  This program send a patch change command to an
//               External MIDI synthesizer.  Usage:
//               midipc instrument-number [midi-device-number]
//
#include
#include
#include
#include
#include
#include


// global variables:
int         seqfd = -1;               // sequencer file descriptor
const char* dev = "/dev/sequencer";   // name of sequencer device
int         status;                   // for error checking

// function declarations:
void sendPatchChange(int device, int patchnum);

int main(int argc, char** argv) {
   int numMidi = 0;                   // number of available MIDI outputs
   int instrument = 0;                // instrument to play (default = piano)
   int device = 0;                    // for selecting which MIDI output to use
   seqfd = open(dev, O_WRONLY, 0);
   if (seqfd < 0) {
      printf("Error: cannot open %s\n", dev);
      exit(1);
   }
   if (argc >= 2) {
      instrument = atoi(argv[1]);
   }
   if (argc >= 3) {
      device = argv[2][0] - '0';
   }
   status = ioctl(seqfd, SNDCTL_SEQ_NRMIDIS, &numMidi);
   if (status != 0) {
      printf("Error: cannot access MIDI devices on soundcard\n");
      exit(1);
   }
   printf("\nThere are: %d MIDI output devices available\n", numMidi);
   if (device >= numMidi) {
      printf("You specified an invalid MIDI device\n");
      exit(1);
   }
   printf("Device set to: %d\n", device);
   sendPatchChange(device, instrument);
   close(seqfd);
   return 0;
}

void sendPatchChange(int device, int patchnum) {
   unsigned char outpacket[8];
   outpacket[0] = SEQ_MIDIPUTC;
   outpacket[1] = 0xc0;              // patch change command (Channel 0)
   outpacket[2] = device;
   outpacket[3] = 0;
   outpacket[4] = SEQ_MIDIPUTC;
   // outpacket[5] will be the instrument number
   outpacket[6] = device;
   outpacket[7] = 0;
   outpacket[5] = patchnum & 0xff;
   write(seqfd, outpacket, 8);
}

############################################
// Syntax:        C++
// $Smake:        cc -g -c %b.cpp -I../../../include && rm -f %b.o
//

#include "SigTimer.h"
#include
#include


// get Sleep or usleep function definition for measureCpu function:
#ifdef VISUAL
   #define WIN32_LEAN_AND_MEAN
   #include             
   #undef WIN32_LEAN_AND_MEAN
#else
   #include
   #include
#endif


// declare static variables
int64bits SigTimer::globalOffset = 0;
int       SigTimer::cpuSpeed     = 0;      // in cycles per second

//////////////////////////////
//
// SigTimer::SigTimer
//
SigTimer::SigTimer(void) {
   if (globalOffset == 0) {             // coordinate offset between timers
      globalOffset = clockCycles();
   }
   if (cpuSpeed <= 0) {                 // initialize CPU speed value
      cpuSpeed = measureCpuSpeed(1);
      if (cpuSpeed <= 0) {
         cpuSpeed = 100000000;
      }
   }
     
   offset = globalOffset;               // initialize the start time of timer
   ticksPerSecond = 1000;               // default of 1000 ticks per second
   period = 1000.0;                     // default period of once per second
}

SigTimer::SigTimer(int aSpeed) {
   if (globalOffset == 0) {
      globalOffset = clockCycles();
   }
   cpuSpeed = aSpeed;
   offset = globalOffset;
   ticksPerSecond = 1000;
   period = 1000.0;                     // default period of once per second
}

SigTimer::SigTimer(SigTimer& aTimer) {
   offset = aTimer.offset;
   ticksPerSecond = aTimer.ticksPerSecond;
   period = aTimer.period;
}

//////////////////////////////
//
// SigTimer::~SigTimer
//
SigTimer::~SigTimer() {
   // do nothing
}

//////////////////////////////
//
// SigTimer::clockCycles -- returns the number of clock cycles since last reboot
//    HARDWARE DEPENDENT -- currently for Pentiums only.
//     static function.
//

int64bits SigTimer::clockCycles() {
#ifndef VISUAL
   int64bits output;
   // For Pentiums, you can get the number of clock cycles elapsed
   // since the last reboot with the following assembler code:
   __asm__ volatile (".byte 0x0f, 0x31" : "=A" (output));
#else
   int64bits output;
   unsigned long high_end, low_end;
   __asm {
      __asm _emit 0x0f __asm _emit 0x31
      mov high_end, edx
      mov low_end, eax
   }
   output = high_end;
   output = output << 32;
   output += low_end;
#endif
   return output;
}

############################################

Keine Kommentare:

Kommentar veröffentlichen

Hinweis: Nur ein Mitglied dieses Blogs kann Kommentare posten.