// ****************************
// 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
http://www.electro-tech-online.com/thre ... ge.112319/
[ add comment ] | [ 0 trackbacks ] | permalink
[ add comment ] | [ 0 trackbacks ] | permalink
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
[ add comment ] | [ 0 trackbacks ] | permalink | related link
#!/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 '>> interrupt counts:'
for nr in xrange(1, len(interrupt_count_dict)):
print '%s, ' % int(interrupt_count_dict[nr]),
print '>> timer ticks:'
for nr in xrange(1, len(interrupt_count_dict)):
print '%s, ' % int(timer_ticks_dict[nr]),
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
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 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
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
/*
* TA0CCTL0, Capture/Compare Control Register 0
*
* CM_1 -- Rising Edge
* CCIS_0 -- CCIxA
* ~SCS -- Asynchronous Capture
* ~SCCI -- Latched capture signal (read)
* ~CAP -- Compare mode
* OUTMOD_0 -- PWM output mode: 0 - OUT bit value
*
* Note: ~<BIT> indicates that <BIT> has value zero
*/
TA0CCTL0 = CM_1 | CCIS_0 | OUTMOD_0 | CCIE;
/* TA0CCR0, Timer_A Capture/Compare Register 0 */
TA0CCR0 = 31;
/*
* TA0CTL, Timer_A3 Control Register
*
* TASSEL_0 -- TACLK
* ID_0 -- Divider - /1
* MC_1 -- Up Mode
*/
TA0CTL = TASSEL_0 | ID_0 | MC_1;
[ add comment ] | [ 0 trackbacks ] | permalink