孔子微言春秋大义
孔子虽然对后世门生不通儒义却又峨冠博带无暇顾及,但他可以对“礼崩乐坏”的纷乱时局抒发自己的愤懑。看到“周公”他老人家于公元前1037年制定的“礼乐游戏”被众家诸侯无情践踏,孔子忍不住发出“八佾舞于庭,是可忍也,孰不可忍”的怒吼。由于出生在鲁国都城曲阜,孔子对“礼乐游戏”极其看重和维护。鲁国是周公的封国,周公在朝中辅政,就由自己的儿子“伯禽”代为监管封国。《史记卷三十三.鲁周公世家第三》记载,周武王『封周公旦于少昊之虚曲阜,是为鲁公。周公不就封,留佐武王』。周公制定了“礼乐”, “曲阜”顺理成章成为天下“文化之都”,与“洛阳”及“朝歌”并称。“洛阳”是成周都城,“道祖”老聃在此博览王室典籍,最终明悟道家奥义。位于河南鹤壁淇县的“朝歌”是殷商都城,后来成为卫国都城。朝歌文化气息馥郁,君子之风蔚然,吴公子札巡访中原后评价“卫多君子,其国无患”。
“文化之都”曲阜户口的孔子具有强烈的“首都市民意识”及“朝阳群众精神”,本着“天下的事就是鲁国的事,鲁国的事就是曲阜的事,曲阜的事就是他的事”这个原则,他决定给诸侯大夫的所作所为截图存档,用『见之於行事之深切著明』来替代『载之空言』。他要『贬天子,退诸侯,讨大夫,以达王事,上明三王之道,下辨人事之纪,别嫌疑,明是非,定犹豫,善善恶恶,贤贤贱不肖,存亡国,继绝世,补敝起废』,宏扬天地正气,阐明礼义大宗,树立天下仪表。于是他用极为精练的语言按照年序编排记录了一份“流水”,『句含褒贬,言微义大,是非二百四十二年之中』。从公元前722年开始,到公元前481年截止,跨度242年的记录共用了一万八千余字。这些记录部分已经遗失,现存一万六千余字。这份“流水”作为章节目录,后来由左丘明、公羊高、谷梁赤三人各自填文,著成《春秋三传》,列入儒家经典当中。
《春秋三传》的三位作者中,左丘明居于山东泰安肥城,担任鲁国的左史官。他比孔子小6岁,为人品行高洁,熟悉诸国史事,深知孔子思想,『孔子将修春秋,与左丘明乘,如周,观书于周史,归而修春秋之经,丘明为之传,共为表里』。左丘明的“传文”与孔子的“经文”同时出炉,解经为辅,叙事为主,对史事记载相当详细。“公羊高”跟“谷梁赤”是孔子的弟子“卜商”,也叫“子夏”的徒弟。子夏比孔子小43岁,位列“孔门十哲”、七十二贤。子夏擅长“文学”,教授弟子《诗经》和《春秋经》,公羊高跟谷梁赤一脉相承,师从子夏研习《春秋经》,见解侧重各有不同。《公羊传》以问答形式解经,着重阐释“微言”和“大义”,对史事记载比较简略。《谷梁传》同样以问答形式解经,侧重传《春秋》“义理”,持论比《公羊传》平正。东汉末年大儒郑玄在《六艺论》中评价,“左氏善於礼,公羊善於谶,谷梁善於经”,东晋大儒范宁在《春秋榖梁经传集解序》中评论《春秋三传》的特色,指出『《左氏》艳而富,其失也巫。《谷梁》清而婉,其失也短。《公羊》辩而裁,其失也俗』,“左传”的缺点在于史料涉及“巫术、祸福、预言”过多,“谷梁传”的缺点在于史料引用不足,不够支撑论证,“公羊传”的缺点在于逻辑推理不够缜密。
虽然未能做到“尽善尽美”,“春秋”一经三传已经足以让我们了解风靡当年的那些“游戏”了。公元前770年周平王迁都洛阳,周王室这个带头大哥由“陕西省长”自动降级为“河南洛阳市长”,游戏就此开局。公元前738年,楚国君主“熊通”灭掉位于湖北宜昌当阳的“权国”后,以权国故地设置权县,“郡县制”游戏开始。公元前722年“郑伯克段于鄢”,“颠覆宗法制”游戏开始。尽管郑庄公的弟弟“共叔段”没有成功,但晋国的“曲沃武公”在公元前678年通关成功,达成“小宗取代大宗”的成就。公元前719年“州吁弑卫桓公”,“春秋弑君”游戏开始,从此三十六位春秋君主次第登上“弑君龙虎榜”。“春秋弑君”游戏游戏也是对“颠覆宗法制”游戏的有力补充。公元前704年,“湖北省长”熊通自封“楚武王”,“诸侯称王”游戏开始。公元前681年,齐桓公在位于山东聊城的“北杏”会盟宋、陈、蔡、邾等诸侯,“诸侯代天子”游戏开始,夏、商、周三代时期只有“天子”才能担当的“带头大哥”角色此后可以由诸侯扮演。公元前633年,晋文公设立三军“六卿”制度,拉开“卿大夫代诸侯”游戏的序幕。公元前594年,鲁国实行按亩征税的田赋制度,这是承认土地私有合法化的开始。公元前562年,鲁国『三桓强于公室』。公元前550年,晋国“六卿十一家族”经过多年兼并,已经只剩下六家。公元前536年,郑国国相“子产”率先铸造刑鼎,“颠覆分封制”游戏开始。公元前513年,晋国的赵鞅、荀寅也把范宣子制作的成文法铸在了铁鼎上公之于众。公元前504年,季氏家臣“阳虎”擅权,“士代卿大夫”游戏开始。公元前457年,晋国韩、赵、魏三家联合击败“智氏”,分了“智氏”家的地盘,建立韩、赵、魏三个政权。公元前403年,周威烈王封三家为侯国,正式承认他们诸侯的地位。韩、赵、魏三家率先通关“卿大夫代诸侯”游戏。公元前386年,周安王正式册命“田和”为齐侯,“田氏”通关“卿大夫代诸侯”游戏。
春秋时期这些全民参与并且风靡一时的游戏具有一个共同的特点,即游戏的结果都是会提供更好的机会给更多的人们,而且这些“更多的人们”是来自于“更低的阶层”。 周天子和他分封的众家诸侯,经过多年的养尊处优后变得既傲慢又无能,与新崛起的“蛮夷”及“士大夫”过招时不堪一击。天子的失势成就了诸侯,诸侯的失势成就了大夫,大夫的失势成就了士人。公田的利益普及到私田,嫡子的权力普及到庶子,贵族的教育普及到平民。虽然这些游戏的结果很美好,孔子却并不喜欢,他想玩的是“克己复礼”游戏。他是个责任心爆棚的“首都市民”,一直想要恢复周公“礼乐”约束下维持的那种“中国式美利坚”格局,有一个统一的“联邦”,有数十个各具特色的“州府”,大家其乐融融。然而孔子想玩的这个游戏已经过时,诸侯大夫都不陪他玩,『诸侯害之,大夫壅之』。孔子最终也不得不接受『言不用,道不行』的事实。
#
#把十进制数按照小尾字节序切割
def littleEndian(number, byte = 4):
result = [0]*byte;
for i in range(byte):
result[i] = number%256;
number//=256;
return result;
#把UltraEdit中的值字串转化为hex序列组
def hexExpr(string):
resultString = '';
size = len(string);
for i in range(size):
if (i == 0 ):
resultString += '0x'+string[i];
elif (string[i] == ' '):
resultString += ', 0x';
else:
resultString += string[i];
print(resultString);
###
# @usage 写.wav文件,能把声波数据阵列用二进制写成.wav。
# @author mw
# @date 2016年04月28日 星期四 14:31:34
# @param
# @return
#
###
def writeWav(index , filename):
byteArray = [];
dataArray = [];
mode = 1;
#样本数据阵列
sampleArray = songArray();
#样本数据点数
N = len(sampleArray);
times = 1;
dataSize = N*times;
fileSize = dataSize+44; #44为格式头部分所用字节数
#RIFF WAVE CHUNK
RIFF_ID = [0x52, 0x49, 0x46, 0x46]; #'RIFF'
RIFF_Size = littleEndian(fileSize-8, 4); #文件总字节数减去8
RIFF_Type = [0x57, 0x41,0x56, 0x45, 0x66, 0x6D, 0x74, 0x20]; #'WAVEfat '
#Format Chunk
Format_10_17 = [0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00];#过滤4+格式2+声道2=8个字节
Format_18_1B = [0x11, 0x2B, 0x00, 0x00]; #采样频率0x2B11 = 11025
Format_1C_1F = [0x22, 0x56, 0x00, 0x00]; #比持率 = 频率*通道*样本位 = 22050
Format_20_23 = [0x02, 0x00, 0x10, 0x00]; #块对齐 = 通道数* 样本位数 = 1*2 = 2
#Fact Chunk(optional)
#Data Chunk
Data_24_27 = [0x64, 0x61, 0x74, 0x61]; #'DATA'标记
Data_Size = littleEndian(fileSize-44, 4); #下面的Data部分的字节数,文件总字节数-44
#RIFF WAVE CHUNK
'''
for i in range(4):
byte = struct.pack('B', RIFF_ID[i]);
byteArray.append(byte);
'''
RIFF = [b'R', b'I', b'F', b'F'];
for i in range(4):
byteArray.append(RIFF[i]);
for i in range(4):
byte = struct.pack('B', RIFF_Size[i]);
byteArray.append(byte);
'''
for i in range(8):
byte = struct.pack('B', RIFF_Type[i]);
byteArray.append(byte);
#Format Chunk
for i in range(8):
byte = struct.pack('B', Format_10_17[i]);
byteArray.append(byte);
for i in range(4):
byte = struct.pack('B', Format_18_1B[i]);
byteArray.append(byte);
for i in range(4):
byte = struct.pack('B', Format_1C_1F[i]);
byteArray.append(byte);
for i in range(4):
byte = struct.pack('B', Format_20_23[i]);
byteArray.append(byte);
#Data Chunk
for i in range(4):
byte = struct.pack('B', Data_24_27[i]);
byteArray.append(byte);
'''
#Format_28_2B是数据块大小,formatHead是它前面的所有部分
formatHead = [b'W', b'A', b'V', b'E', b'f', b'm', b't', b' ', \
b'\x10', b'\x00', b'\x00', b'\x00', b'\x01', b'\x00', b'\x01', b'\x00', \
b'\x11', b'+', b'\x00', b'\x00', \
b'"', b'V', b'\x00', b'\x00', \
b'\x02', b'\x00', b'\x10', b'\x00', \
b'd', b'a', b't', b'a'];
for i in range(len(formatHead)):
byteArray.append(formatHead[i]);
for i in range(4):
byte = struct.pack('B', Data_Size[i]);
byteArray.append(byte);
#写出到文件
print('文件写入开始。>>>');
s = '';
if mode == 1:
s = filename+'_'+str(index)+'.wav';
elif mode == 2:
s = 'randMusic'+str(index)+'.wav';
fout= open(s, 'wb');
size = len(byteArray);
for i in range(size):
fout.write(byteArray[i]);
size = len(sampleArray);
sizeIdle = len(idleWave);
for j in range(times):
for i in range(size):
fout.write(sampleArray[i]);
fout.close();
print('文件写入完毕。');
#歌曲数据
def songArray():
'''
#钢琴音符的频率
A4 = 440 #440Hz
C4 = 261.62557 #
coef = 2**(1/12);
low = [];
high = [];
a = 440;
for i in range(48):
a = round(a / coef, 3)
low.append(a);
a = 440;
for i in range(36):
a = round(a * coef, 3);
high.append(a);
res = list(reversed(low)) + [A4] + high;
for i in range(len(res)):
print('{0:.3f}'.format(res[i]), end = ', ');
if i%6 == 5:
print('');
'''
#频率
FreqPiano = [[27.500, 29.135, 30.867, 32.702, 34.647, 36.707,
38.890, 41.203, 43.653, 46.249, 48.999, 51.913], #O1
[55.000, 58.270, 61.735, 65.406, 69.295, 73.416,
77.782, 82.407, 87.307, 92.499, 97.999, 103.826], #O2
[110.000, 116.541, 123.471, 130.813, 138.592, 146.833,
155.564, 164.814, 174.614, 184.997, 195.997, 207.652], #O3
[220.000, 233.082, 246.942, 261.626, 277.183, 293.665,
311.127, 329.628, 349.229, 369.995, 391.996, 415.305], #O4
[440.000, 466.164, 493.884, 523.252, 554.366, 587.330,
622.254, 659.255, 698.456, 739.988, 783.990, 830.608], #O5
[879.999, 932.326, 987.765, 1046.501, 1108.729, 1174.657,
1244.506, 1318.508, 1396.911, 1479.976, 1567.980, 1661.217], #O6
[1759.998, 1864.653, 1975.531, 2093.002, 2217.458, 2349.315,
2489.013, 2637.017, 2793.822, 2959.951, 3135.959, 3322.433]] #O7
#调式
Tone = [['C', [1, 3, 5, 6, 8, 10, 12]], #以CDEFGAB顺序排音 'a'
['G', [13, 15, 17, 19, 8, 10, 12]], #'e'
['D', [13, 3, 5, 7, 8, 10, 12]], #'b'
['A', [14, 15, 17, 19, 21, 10, 12]], #'#f'
['E', [14, 16, 5, 7, 9, 10, 12]], #'#c'
['B', [14, 16, 17, 19, 21, 23, 12]] #'#g'
];
#卷珠帘
JuanZhuLian = [['G', 4, 4, 100], #G大调,4/4拍, 90拍/分钟
#第一节
[5, 6/16, 4, 2/16, 4, 4/16, 3, 4/16],
[2, 6/16, 2, 2/16, 2, 4/16, 1, 2/16, -6, 2/16],
[-6, 2/16, -5, 2/16, -5, 12/16],
[0, 8/16, 4, 4/16, 11, 4/16],
[7, 6/16, 6, 2/16, 6, 4/16, 5, 4/16],
[6, 16/16],
[6, 8/16, 6, 4/16, 11, 2/16, 12, 2/16],
[12, 8/16, 11, 2/16, 12, 1/16, 11, 1/16, 6, 2/16, 5, 2/16],
[5, 8/16, 4, 4/16, 5, 4/16],
[6, 4/16, 5, 2/16, 4, 2/16, 4, 2/16, 5, 1/16, 4, 1/16, 2, 2/16, 1, 2/16],
[2, 12/16, 1, 4/16],
[2, 12/16, 4, 4/16],
#第一尾
[3, 4/16, 1, 2/16, -6, 2/16, 5, 4/16, 4, 2/16, 2, 2/16],
[2, 2/16, 2, 2/16, 2, 12/16],
[2, 16/16],
[0, 16/16],
[0, 16/16],
#第二节 基本同第一节
[5, 6/16, 4, 2/16, 4, 4/16, 3, 4/16],
[2, 6/16, 2, 2/16, 2, 4/16, 1, 2/16, -6, 2/16],
[-6, 2/16, -5, 2/16, -5, 12/16],
[0, 8/16, 4, 4/16, 11, 4/16],
[7, 6/16, 6, 2/16, 6, 4/16, 5, 4/16],
[6, 16/16],
[6, 8/16, 6, 4/16, 11, 2/16, 6, 1/16, 11, 1/16],
[12, 8/16, 11, 2/16, 12, 1/16, 11, 1/16, 6, 2/16, 5, 2/16],
[5, 8/16, 4, 4/16, 5, 4/16],
[6, 4/16, 5, 2/16, 4, 2/16, 4, 2/16, 5, 1/16, 4, 1/16, 2, 2/16, 1, 2/16],
[2, 12/16, 1, 4/16],
[2, 12/16, 4, 4/16],
#第二尾
[3, 4/16, 1, 2/16, -6, 2/16, 5, 4/16, 4, 2/16, 2, 2/16],
[2, 2/16, 4, 2/16, 2, 12/16],
[2, 4/16, 0, 4/16, 0, 4/16, 11, 4/16],
[2, 12/16, 2, 2/16, 13, 1/16, 12, 1/16],
[11, 6/16, 12, 1/16, 11, 1/16, 7, 4/16, 6, 4/16],
[7, 4/16, 6, 2/16, 5, 2/16, 2, 8/16],
[2, 8/16, 3, 4/16, 4, 4/16],
[4, 2/16, 11, 2/16, 11, 8/16, 11, 2/16, 11, 1/16, 12, 1/16],
[7, 8/16, 7, 4/16, 6, 2/16, 5, 2/16],
[4, 2/16, 5, 2/16, 6, 12/16],
[0, 12/16, 11, 4/16],
[12, 12/16, 12, 2/16, 13, 1/16, 12, 1/16],
[11, 6/16, 12, 1/16, 11, 1/16, 7, 4/16, 6, 2/16, 5, 2/16],
[7, 4/16, 6, 2/16, 5, 2/16, 6, 2/16, 5, 6/16],
[5, 8/16, 6, 4/16, 5, 4/16],
[2, 16/16],
[0, 4/16, 6, 2/16, 5, 2/16, 2, 6/16, 1, 2/16],
[2, 16/16],
[2, 16/16],
[0, 16/16],
[0, 16/16],
#第三节 同第二节
[5, 6/16, 4, 2/16, 4, 4/16, 3, 4/16],
[2, 6/16, 2, 2/16, 2, 4/16, 1, 2/16, -6, 2/16],
[-6, 2/16, -5, 2/16, -5, 12/16],
[0, 8/16, 4, 4/16, 11, 4/16],
[7, 6/16, 6, 2/16, 6, 4/16, 5, 4/16],
[6, 16/16],
[6, 8/16, 6, 4/16, 11, 2/16, 6, 1/16, 11, 1/16],
[12, 8/16, 11, 2/16, 12, 1/16, 11, 1/16, 6, 2/16, 5, 2/16],
[5, 8/16, 4, 4/16, 5, 4/16],
[6, 4/16, 5, 2/16, 4, 2/16, 4, 2/16, 5, 1/16, 4, 1/16, 2, 2/16, 1, 2/16],
[2, 12/16, 1, 4/16],
[2, 12/16, 4, 4/16],
#第三尾
[3, 4/16, 1, 2/16, -6, 2/16, 5, 4/16, 4, 2/16, 2, 2/16],
[2, 2/16, 1, 2/16, 2, 12/16],
[2, 16/16]
];
#强弱节拍
strong = [[1.0, 0.8, 0.9, 0.8], #4/4拍
[1.0, 0.8, 0.8], #3/4拍
[1.0, 0.9], #2/4拍
[1.0, 0.8, 0.7, 1.0, 0.8, 0.7] #6/8拍
];
#旋律
music = JuanZhuLian;
print('曲谱检查开始');
#乐谱简单检查
for i in range(1, len(music)):
len_ = len(music[i]);
if (len_%2 != 0):
raise Exception('第{0}节歌曲--{1}--数据有误,请检查!'.format(i, music[i]));
totalendure = 0;
if (len_ != 0):
for j in range(0, len_, 2):
totalendure += music[i][j+1];
if (round(totalendure * 16))%4 != 0:
raise Exception('第{0}节歌曲--{1}--数据有误,请检查!'.format(i, music[i]));
print('根据调式选音开始');
keyFreq = [];
key = [];
level = 3;
if (music[0][0] == 'G'): #G大调
key = Tone[1][1];
else:
pass;
for j in range(3): #低中高三阶音, 共21个键的音
keyFreq_ = [];
for i in range(7):
freq_ = key[i]+1; #对应到键音频率表
if (freq_ >= 12):
keyFreq_.append(FreqPiano[level+j][freq_ - 12]);
else:
keyFreq_.append(FreqPiano[level+j-1][freq_]);
keyFreq.append(keyFreq_);
#print(keyFreq);
#每拍时间
clapendure = 60/music[0][3];
#二进制数据
data = [];
#切分音使用指示
continuous = True;
print('--歌曲数据生成开始--');
if (music[0][1] == 4 and music[0][2] == 4): #4/4拍
clap = strong[0]; #拍子强弱
for k in range(1, len(music)):
start = 0;
clapsection = 0;
explode = []; #小节内分解
for j in range(0, len(music[k]), 2):
#print(music[i][j], end = ', ');
endure = music[k][j+1]; #持续时间
#print('i', i, 'j', j);
#print(endure);
if (continuous == False):
#不使用切分音的场合,同一个音符轻重不同
spare = 0.25 - start;
if (spare >= endure):
explode.append([music[k][j], endure, clap[clapsection]]);
else:
if (start + endure > 0.75):
explode.append([music[k][j], spare, clap[clapsection]]);
explode.append([music[k][j], 0.25, clap[clapsection+1]]);
explode.append([music[k][j], 0.25, clap[clapsection+2]]);
start = endure-0.5-spare;
explode.append([music[k][j], start, clap[clapsection+3]]);
clapsection += 3;
elif (start + endure > 0.5):
explode.append([music[k][j], spare, clap[clapsection]]);
explode.append([music[k][j], 0.25, clap[clapsection+1]]);
start = endure-0.25-spare;
explode.append([music[k][j], start, clap[clapsection+2]]);
clapsection += 2;
elif (start + endure > 0.25):
explode.append([music[k][j], spare, clap[clapsection]]);
start = endure-spare;
explode.append([music[k][j], start, clap[clapsection+1]]);
clapsection += 1;
else:
pass;
else: #使用切分音
explode.append([music[k][j], endure, clap[clapsection]]);
start += endure;
if (start >= 0.75):
start -= 0.75;
clapsection = 3;
elif (start >= 0.5):
start -= 0.5;
clapsection = 2;
elif start >= 0.25:
start -= 0.25;
clapsection = 1;
else:
clapsection = 0;
for i in range(len(explode)):
endure_ = explode[i][1]/0.25*clapendure;
if (explode[i][0] == 0): #空音
data += zeropack(endure_);
elif (explode[i][0] > 10): #高音
freq_ = keyFreq[2][explode[i][0]-10-1];
data += wavepack(datawave(freq_, endure_, explode[i][2]));
elif (explode[i][0] < 0): #低音
freq_ = keyFreq[0][explode[i][0]+10-1];
data += wavepack(datawave(freq_, endure_, explode[i][2]));
else:
freq_ = keyFreq[1][explode[i][0]-1];
data += wavepack(datawave(freq_, endure_, explode[i][2]));
else: #其它节奏
pass;
#print(data[:100]);
#print(len(data));
return data;
#波形数据
def datawave(freq, endure, strong):
#传入频率、持续时间,拍子强度
#设立20000个数值点,约可听2秒
sampleArray = [];
coef = 2*math.pi*freq/11025;
N = round(endure*11025);
for i in range(N):
xvalue = coef*i;
yvalue = math.sin(xvalue)
if (yvalue < 0):
yvalue *= strong * 32768/2;
else:
yvalue *= strong * 32767/2;
sampleArray.append(round(yvalue));
return sampleArray;
#波形压缩成二进制
def wavepack(wavedata):
dataArray = [];
for i in range(len(wavedata)):
value = littleEndian(wavedata[i], 2);
for j in range(2):
byte = struct.pack('B', value[j]);
dataArray.append(byte);
return dataArray;
#空音压缩成二进制
def zeropack(endure):
N = round(endure*11025)//2;
return [b'\x00', b'\x00']*N;
#