/* * VsqNrpn.cs * Copyright (c) 2008-2009 kbinani * * This file is part of Boare.Lib.Vsq. * * Boare.Lib.Vsq is free software; you can redistribute it and/or * modify it under the terms of the BSD License. * * Boare.Lib.Vsq is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ using System; using System.Collections.Generic; namespace Boare.Lib.Vsq { public struct VsqNrpn : IComparable { public int Clock; public ushort Nrpn; public byte DataMsb; public byte DataLsb; public bool DataLsbSpecified; public bool msbOmitRequired; private List m_list; public VsqNrpn( int clock, ushort nrpn, byte data_msb ) { Clock = clock; Nrpn = nrpn; DataMsb = data_msb; DataLsb = 0x0; DataLsbSpecified = false; msbOmitRequired = false; m_list = new List(); } public VsqNrpn( int clock, ushort nrpn, byte data_msb, byte data_lsb ) { Clock = clock; Nrpn = nrpn; DataMsb = data_msb; DataLsb = data_lsb; DataLsbSpecified = true; msbOmitRequired = false; m_list = new List(); } public VsqNrpn[] expand() { List ret = new List(); if ( DataLsbSpecified ) { VsqNrpn v = new VsqNrpn( Clock, Nrpn, DataMsb, DataLsb ); v.msbOmitRequired = msbOmitRequired; ret.Add( v ); } else { VsqNrpn v = new VsqNrpn( Clock, Nrpn, DataMsb ); v.msbOmitRequired = msbOmitRequired; ret.Add( v ); } for ( int i = 0; i < m_list.Count; i++ ) { ret.AddRange( m_list[i].expand() ); } return ret.ToArray(); } public static List sort( List list ) { List ret = new List(); list.Sort(); if ( list.Count >= 2 ) { List work = new List(); //workには、clockが同じNRPNだけが入る int last_clock = list[0].Clock; work.Add( list[0] ); for ( int i = 1; i < list.Count; i++ ) { if ( list[i].Clock == last_clock ) { work.Add( list[i] ); } else { // まずworkを並べ替え last_clock = list[i].Clock; bool changed = true; while ( changed ) { changed = false; for ( int j = 0; j < work.Count - 1; j++ ) { byte nrpn_msb0 = (byte)((work[j].Nrpn >> 8) & 0xff); byte nrpn_msb1 = (byte)((work[j + 1].Nrpn >> 8) & 0xff); if ( nrpn_msb1 > nrpn_msb0 ) { VsqNrpn buf = work[j]; work[j] = work[j + 1]; work[j + 1] = buf; changed = true; } } } for ( int j = 0; j < work.Count; j++ ) { ret.Add( work[j] ); } work.Clear(); work.Add( list[i] ); } } for ( int j = 0; j < work.Count; j++ ) { ret.Add( work[j] ); } } else { for ( int i = 0; i < list.Count; i++ ) { ret.Add( list[i] ); } } return ret; } public static VsqNrpn[] merge( VsqNrpn[] src1, VsqNrpn[] src2 ) { List ret = new List(); for ( int i = 0; i < src1.Length; i++ ) { ret.Add( src1[i] ); } for ( int i = 0; i < src2.Length; i++ ) { ret.Add( src2[i] ); } ret.Sort(); return ret.ToArray(); } public static NrpnData[] convert( VsqNrpn[] source ) { ushort nrpn = (ushort)source[0].Nrpn; byte msb = (byte)(nrpn >> 8); byte lsb = (byte)(nrpn - (nrpn << 8)); List ret = new List(); ret.Add( new NrpnData( source[0].Clock, 0x63, msb ) ); ret.Add( new NrpnData( source[0].Clock, 0x62, lsb ) ); ret.Add( new NrpnData( source[0].Clock, 0x06, source[0].DataMsb ) ); if ( source[0].DataLsbSpecified ) { ret.Add( new NrpnData( source[0].Clock, 0x26, source[0].DataLsb ) ); } for ( int i = 1; i < source.Length; i++ ) { VsqNrpn item = source[i]; ushort tnrpn = item.Nrpn; msb = (byte)(tnrpn >> 8); lsb = (byte)(tnrpn - (tnrpn << 8)); if ( item.msbOmitRequired ) { ret.Add( new NrpnData( item.Clock, 0x62, lsb ) ); ret.Add( new NrpnData( item.Clock, 0x06, item.DataMsb ) ); if ( item.DataLsbSpecified ) { ret.Add( new NrpnData( item.Clock, 0x26, item.DataLsb ) ); } } else { ret.Add( new NrpnData( item.Clock, 0x63, msb ) ); ret.Add( new NrpnData( item.Clock, 0x62, lsb ) ); ret.Add( new NrpnData( item.Clock, 0x06, item.DataMsb ) ); if ( item.DataLsbSpecified ) { ret.Add( new NrpnData( item.Clock, 0x26, item.DataLsb ) ); } } } return ret.ToArray(); } public int CompareTo( VsqNrpn item ) { return Clock - item.Clock; } public void append( ushort nrpn, byte data_msb ) { m_list.Add( new VsqNrpn( Clock, nrpn, data_msb ) ); } public void append( ushort nrpn, byte data_msb, byte data_lsb ) { m_list.Add( new VsqNrpn( Clock, nrpn, data_msb, data_lsb ) ); } public void append( ushort nrpn, byte data_msb, bool msb_omit_required ) { VsqNrpn v = new VsqNrpn( Clock, nrpn, data_msb ); v.msbOmitRequired = msb_omit_required; m_list.Add( v ); } public void append( ushort nrpn, byte data_msb, byte data_lsb, bool msb_omit_required ) { VsqNrpn v = new VsqNrpn( Clock, nrpn, data_msb, data_lsb ); v.msbOmitRequired = msb_omit_required; m_list.Add( v ); } } }