parse midi messages 

// parse midi message
void receive_midi(void)
{
while( ( buf_input_ptr & 0x0f ) != ( buf_input_prc & 0x0f ) )
{
// a new byte arrived
buf_input_prc++; // pointer to processed data
midi_in = buf_input[ buf_input_prc & 0x0f ];

if( midi_in >> 7 )
{
midi_event = midi_in & 0xf0;
midi_channel = midi_in & 0x0f;
midi_in_data_cnt = 0;
midi_key = 0;
midi_velocity = 0;
}

if( midi_event != 0xf0 )
{
// increase the counter as we parse data

// ****************************
//
// Channel Voice Messages
//
// ****************************
switch( midi_event )
{
case NOTE_OFF_EVENT:
switch( midi_in_data_cnt )
{
case 0:
printf_lcd_fb( "NOTE_OFF_EVENT" );
break;
case 1:
// key = parse_key ( midi_in_data );
midi_key = midi_in;
break;
case 2:
midi_velocity = midi_in;
printf_lcd_fb( "NOTE_OFF_EVENT; \nev: %d ch: %d; \nkey: %d\nvel: %d", \
midi_event, midi_channel, midi_key, midi_velocity );
break;
default:
printf_lcd_fb( "NOTE_OFF_EVENT\nextra data?!\ngot %d bytes more", \
( midi_in_data_cnt - NOTE_OFF_EVENT_BC ) );
break;
}
midi_in_data_cnt++;
break;

case NOTE_ON_EVENT:
switch( midi_in_data_cnt )
{
case 0:
printf_lcd_fb( "NOTE_ON_EVENT" );
break;
case 1:
// key = parse_key ( midi_in_data );
midi_key = midi_in;
break;
case 2:
midi_velocity = midi_in;
printf_lcd_fb( "NOTE_ON_EVENT; \nev: %d ch: %d; \nkey: %d\nvel: %d", \
midi_event, midi_channel, midi_key, midi_velocity );
break;
default:
printf_lcd_fb( "NOTE_ON_EVENT\nextra data?!\ngot %d bytes more", \
( midi_in_data_cnt - NOTE_ON_EVENT_BC ) );
break;
}
midi_in_data_cnt++;
break;

case POLYPHONIC_KEY_PRESSURE:
//printf_lcd( "POLYPHONIC_KEY_PRESSURE: %d, %d", midi_event, midi_channel );
break;

case CONTROL_CHANGE:
printf_lcd( "CONTROL_CHANGE: %d, %d", midi_event, midi_channel );
break;

case PROGRAM_CHANGE:
printf_lcd( "PROGRAM_CHANGE: %d, %d", midi_event, midi_channel );
break;

case CHANNEL_PRESSURE:
printf_lcd( "CHANNEL_PRESSURE: %d, %d", midi_event, midi_channel );
break;

case PITCH_WHELL_CHANGE:
printf_lcd( "PITCH_WHELL_CHANGE: %d, %d", midi_event, midi_channel );
break;
}
} else
{
// ****************************
// System Common Messages
// System Real-Time Messages
// ****************************
switch( midi_event )
{
/*
case SYSTEM_EXCLUSIVE:
printf_lcd( "SYSTEM_EXCLUSIVE" );
break;

case MIDI_TIME_CODE_QUARTER_FRAME:
printf_lcd( "MIDI_TIME_CODE_QUARTER_FRAME" );
break;

case SONG_POSITION_POINTER:
printf_lcd( "SONG_POSITION_POINTER" );
break;

case SONG_SELECT:
printf_lcd( "SONG_SELECT" );
break;

case RESERVED1:
printf_lcd( "RESERVED1" );
break;

case RESERVED2:
printf_lcd( "RESERVED2" );
break;

case TUNE_REQUEST:
printf_lcd( "TUNE_REQUEST" );
break;

case END_OF_EXCLUSIVE:
printf_lcd( "END_OF_EXCLUSIVE" );
break;

case TIMING_CLOCK:
printf_lcd( "TIMING_CLOCK" );
break;

case UNDEFINED3:
printf_lcd( "UNDEFINED3" );
break;

case START:
printf_lcd( "START" );
break;

case CONTINUE:
printf_lcd( "CONTINUE" );
break;

case STOP:
printf_lcd( "STOP" );
break;

case UNDEFINED4:
printf_lcd( "UNDEFINED4" );
break;

case ACTIVE_SENSING:
printf_lcd( "ACTIVE_SENSING" );
break;

case RESET:
printf_lcd( "RESET" );
break;
*/
}
}
}
}


[ add comment ] ( 1 view )   |  [ 0 trackbacks ]   |  permalink
MIDI Code definitons 

// ****************************
// midi code definitions
// ****************************

// http://www.midi.org/techspecs/midimessages.php
// m s g e
// Channel Voice Messages c h n l
#define NOTE_OFF_EVENT BIN(1,0,0,0,0,0,0,0)
#define NOTE_OFF_EVENT_BC 2 // Note Off event.
// 0kkkkkkk + 0vvvvvvv
// This message is sent when a note is released (ended).
// (kkkkkkk) is the key (note) number. (vvvvvvv) is the velocity.

#define NOTE_ON_EVENT BIN(1,0,0,1,0,0,0,0)
#define NOTE_ON_EVENT_BC 2 // Note On event.
// 0kkkkkkk + 0vvvvvvv
// This message is sent when a note is depressed (start).
// (kkkkkkk) is the key (note) number. (vvvvvvv) is the velocity.

#define POLYPHONIC_KEY_PRESSURE BIN(1,0,1,0,0,0,0,0)
#define POLYPHONIC_KEY_PRESSURE_BC 2 // Polyphonic Key Pressure (Aftertouch).
// 0kkkkkkk + 0vvvvvvv
// This message is most often sent by pressing down on the
// key after it "bottoms out". (kkkkkkk) is the key (note)
// number. (vvvvvvv) is the pressure value.

#define CONTROL_CHANGE BIN(1,0,1,1,0,0,0,0)
#define CONTROL_CHANGE_BC 2 // Control Change.
// 0ccccccc + 0vvvvvvv
// This message is sent when a controller value changes.
// Controllers include devices such as pedals and levers.
// Controller numbers 120-127 are reserved as "Channel Mode
// Messages" (below). (ccccccc) is the controller number
// (0-119). (vvvvvvv) is the controller value (0-127).

#define PROGRAM_CHANGE BIN(1,1,0,0,0,0,0,0)
#define PROGRAM_CHANGE_BC 1 // Program Change.
// 0ppppppp
// This message sent when the patch number
// changes. (ppppppp) is the new program number.

#define CHANNEL_PRESSURE BIN(1,1,0,1,0,0,0,0)
#define CHANNEL_PRESSURE_BC 1 // Channel Pressure (After-touch).
// (vvvvvvv) is the pressure value.

#define PITCH_WHELL_CHANGE BIN(1,1,1,0,0,0,0,0)
#define PITCH_WHELL_CHANGE_BC 2 // Pitch Wheel Change.
// 0lllllll + 0mmmmmmm
// This message is sent to
// indicate a change in the pitch wheel. The pitch wheel is
// measured by a fourteen bit value. Center (no pitch change) is
// 2000H. Sensitivity is a function of the transmitter. (llllll) are
// the least significant 7 bits. (mmmmmm) are the most
// significant 7 bits.


// System Common Messages
#define SYSTEM_EXCLUSIVE BIN(1,1,1,1,0,0,0,0)
#define SYSTEM_EXCLUSIVE_BC 65535 // more complicated, not supported yet
// stream ends with END_OF_EXCLUSIVE.

#define MIDI_TIME_CODE_QUARTER_FRAME BIN(1,1,1,1,0,0,0,1)
#define MIDI_TIME_CODE_QUARTER_FRAME_BC 1 // 0nnndddd, where:
// nnn = Message Type
// dddd = Values

#define SONG_POSITION_POINTER BIN(1,1,1,1,0,0,1,0)
#define SONG_POSITION_POINTER_BC 2 // 0lllllll + 0mmmmmmm
// 14 bit register, l is the LSB, m the MSB

#define SONG_SELECT BIN(1,1,1,1,0,0,1,1)
#define SONG_SELECT_BC 1 // 0sssssss
// (sssssss) specifies which sequence
// or song is to be played.

#define RESERVED1 BIN(1,1,1,1,0,1,0,0)
#define RESERVED1_BC 0

#define RESERVED2 BIN(1,1,1,1,0,1,0,1)
#define RESERVED2_BC 0

#define TUNE_REQUEST BIN(1,1,1,1,0,1,1,0) // Tune Request.
// Upon receiving a Tune Request,
// all analog synthesizers should
// tune their oscillators.
#define TUNE_REQUEST_BC 0

#define END_OF_EXCLUSIVE BIN(1,1,1,1,0,1,1,1) // End of Exclusive. Used to terminate
#define END_OF_EXCLUSIVE_BC 0


// a System Exclusive dump (see above).
// System Real-Time Messages
#define TIMING_CLOCK BIN(1,1,1,1,1,0,0,0)
#define TIMING_CLOCK_BC 0 // Timing Clock. Sent 24 times per quarter note when
// synchronization is required (see text).

#define UNDEFINED3 BIN(1,1,1,1,1,0,0,1)
#define UNDEFINED3_BC 0

#define START BIN(1,1,1,1,1,0,1,0)
#define START_BC 0 // Start. Start the current sequence playing. (This message will
// be followed with Timing Clocks).

#define CONTINUE BIN(1,1,1,1,1,0,1,1)
#define CONTINUE_BC 0 // Continue. Continue at the point the sequence was Stopped.

#define STOP BIN(1,1,1,1,1,1,0,0)
#define STOP_BC 0 // Stop. Stop the current sequence.

#define UNDEFINED4 BIN(1,1,1,1,1,1,0,1)
#define UNDEFINED4_BC Undefined. (Reserved)

#define ACTIVE_SENSING BIN(1,1,1,1,1,1,1,0)
#define ACTIVE_SENSING_BC 0 // Active Sensing. This message is intended to be sent
// repeatedly to tell the receiver that a connection is alive. Use of
// this message is optional. When initially received, the receiver
// will expect to receive another Active Sensing message each
// 300ms (max), and if it does not then it will assume that the
// connection has been terminated. At termination, the receiver
// will turn off all voices and return to normal (non- active
// sensing) operation.

#define RESET BIN(1,1,1,1,1,1,1,1)
#define RESET_BC 0 // Reset. Reset all receivers in the system to power-up status.
// This should be used sparingly, preferably under manual
// control. In particular, it should not be sent on power-up.


[ add comment ]   |  [ 0 trackbacks ]   |  permalink
how to limit voltage output of op amp to symetric range 
http://www.electro-tech-online.com/thre ... ge.112319/

[ add comment ]   |  [ 0 trackbacks ]   |  permalink
Basics of Ferrite Beads for Filters, EMI Suppression, Parasitic oscillation suppression 


[ add comment ]   |  [ 0 trackbacks ]   |  permalink
Syllabus C335 Computer Structures 
MSP430

12 MSP430 Getting Started
MSP430 Polling
LaunchPad Introduction
14 MSP430 Architecture (Short version 44 pages) (Long version 871 pages)
MSP430 Assembly Programming
MSP430 C/C++ Programming

Last chance
for HW6-7
19 MSP430 Interrupts 8
26 MSP430 Timers and PWM
28 MSP430 Memory-mapped I/O
MSP430 Serial Communications
MSP430 C/Assembler comparison
3 Dec Review Bring LaunchPad and HW questions
Enrichment readings
Chapter 11. Windows Programming
Chapter 14. Disk Fundamentals.
Chapter 15. BIOS-Level Programming.

[ add comment ]   |  [ 0 trackbacks ]   |  permalink  |  related link
Using the Analog Devices AD9850 DDS 


[ add comment ]   |  [ 0 trackbacks ]   |  permalink  |  related link
Masterscaler 

#!/usr/bin/python
# -*- coding: utf-8 -*-

import time
from decimal import Decimal

# debug on/off
DEBUG = True

# initial settings
twelfth_root_of_two = \
1.059463094359295264561825294946341700779204317494
root_016 = 1.0036166659754629134913855149569
root_032 = 1.0018067009036538249718210506931
root_064 = 1.0009029427989777995544424758581
root_100 = 1.0005777895065548592967925757932
root_128 = 1.0004513695322615727617341558255

# basic generator parameters
base_clock = 16000000 / 2 # 16Khz, but the real frequency is 1/2 (compl. cycle)
root_of_roots = root_032


# functions
def frequency_scaler(base_clock, desired_frequency):
''' base_clock in Hz, desired_frequency in Hz '''

base_clock = float(base_clock)
desired_frequency = float(desired_frequency)

common_denominator = base_clock / desired_frequency
best_effort_computation_round_error_frequency = base_clock

for interrupt_count in range(1, 65535):

timer_ticks = common_denominator // interrupt_count
if timer_ticks > 0 and timer_ticks < 65535 and \
(interrupt_count == 1 or interrupt_count == 2 or interrupt_count == 4 or interrupt_count == 8 \
or interrupt_count == 16 and ( interrupt_count > 18 or interrupt_count < 24 )):

computation_round_error_frequency = (base_clock / (interrupt_count * timer_ticks)) - desired_frequency

if abs(computation_round_error_frequency) < abs(best_effort_computation_round_error_frequency):

best_effort_computation_round_error_frequency = computation_round_error_frequency

selected_interrupt_count = interrupt_count
selected_timer_ticks = timer_ticks

return (selected_interrupt_count, int(selected_timer_ticks), round(best_effort_computation_round_error_frequency, 4))


def generate_subsequent(f):
''' generate base and all the subsequent
frequencies for a given (semi)tone
'''

global note_index
current_frequency = f
note_in_sequence = 0

while note_in_sequence != steps_to_next_note:

(interrupt_count, timer_ticks, error) = frequency_scaler(base_clock, current_frequency)
interrupt_count_dict[note_index] = interrupt_count
timer_ticks_dict[note_index] = timer_ticks

print 'ix: %s/%s, f: %s, midinote: %s, octave: %s, note: %s, intr_count: %s, time_ticks: %s, error: %s' \
% (
note_in_sequence,
note_index,
current_frequency,
midi_note,
octave,
note,
interrupt_count,
timer_ticks,
error
)

if current_frequency == f:
pass
# time.sleep(5)

current_frequency *= root_of_roots
note_index += 1
note_in_sequence += 1


# init variables
interrupt_count_dict = {}
timer_ticks_dict = {}

# note defaults
notes = [
'C ',
'Db',
'D ',
'Eb',
'E ',
'F ',
'Gb',
'G ',
'Ab',
'A ',
'Bb',
'B ',
]


start_tone_frequency = 8.1758 # C0
start_midi_note = 0
steps_to_next_note = 32

f = start_tone_frequency
midi_note = start_midi_note
note_index = 0

# generate frequencies

# one (semi)tone below for down tuning (-offset tuning)
octave = 0
note = 'B '
midi_note = -1
generate_subsequent(start_tone_frequency / twelfth_root_of_two)
midi_note += 1

# generate the rest (along with a +offset tuning)
try:

for octave in xrange(0, 11):

for note in notes:

print '------------- note: %s %s -----------------' \
% (note, octave)
generate_subsequent(f)
midi_note += 1
f *= twelfth_root_of_two

if midi_note > 127:

raise ValueError
except ValueError:

pass


# list computed results
print
print '>> interrupt counts:'
for nr in xrange(1, len(interrupt_count_dict)):

print '%s, ' % int(interrupt_count_dict[nr]),

print
print '>> timer ticks:'
for nr in xrange(1, len(interrupt_count_dict)):

print '%s, ' % int(timer_ticks_dict[nr]),


print
print '>> dictionary sizes:'
print ">> timer_ticks_dict has: %s items" % (len(timer_ticks_dict) - 1 )
print ">> interrupt_count_dict has: %s items" % (len(interrupt_count_dict) - 1 )


[ add comment ]   |  [ 0 trackbacks ]   |  permalink
Converting a pitch bend (MIDI) value to a “normal” pitch value 
The controller message has an argument that goes from -8192 to 8191 and in standard MIDI files this is supposed to cover the range from -200 cent to 200 cent, where 1 cent is 1/100 of semitone, i.e. a ratio of 2^(1/1200) = 1.000577789506555.


[ add comment ]   |  [ 0 trackbacks ]   |  permalink  |  related link
static int  
static int state = 0;

So if you need a variable that is only used within a function and only updated by that function and you need the value of that variable to remain for the next time that you call the function then you need to define it as a static variable.

[ add comment ]   |  [ 0 trackbacks ]   |  permalink
Placing Variables in Specific Memory Location - MSP430 
In many application, it is sometime necessary to place a variable in a specific memory location. This wiki shows a small guide to implement the specific variable placement for C programming language using most common compilers/IDEs for MSP430.

[ add comment ]   |  [ 0 trackbacks ]   |  permalink  |  related link

<<First <Back | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | Next> Last>>