Main Page | Alphabetical List | Class List | Directories | File List | Class Members | File Members

Mini.cpp

Go to the documentation of this file.
00001 
00029 #include <cstring>
00030 #include <cmath>
00031 #include <cstdio>
00032 #include <iostream>
00033 
00034 #include "Mini.hh"
00035 #include "Netmusic.hh"
00036 
00037 //****************************************************************
00038 void Mini::set_mini_word(int* noteArray, int k, char* binaryMiniWord,
00039         int noteOffValue, int* size_mem_mpz, int startKey )
00040 {
00041         mpz_t tempWord1, tempWord2, miniWord;
00042         char* tmp;
00043 
00044         //init mpz
00045         mpz_init(miniWord);
00046         mpz_init(tempWord1);
00047         mpz_init(tempWord2);
00048         mpz_set_ui(miniWord,0);
00049 
00050         // mini calculations
00051         Mini::sort_array(noteArray, k);
00052         Mini::ksub_rank( k, noteArray, miniWord);
00053         mpz_set(tempWord1, miniWord);
00054         mpz_set(tempWord2, miniWord);
00055         *size_mem_mpz = Mini::get_size_mem_mpz(tempWord1);
00056         tmp = new char[(*size_mem_mpz)];
00057         Mini::mpz_2_bin(tempWord2, k, noteOffValue, tmp);
00058         
00059         // set pointer
00060         binaryMiniWord = tmp;
00061 
00062         // print
00063         std::cout << DELIMITER << std::endl;
00064         Mini::print_array(noteArray, k, startKey);// print array
00065         gmp_printf("\n rank: %Zd\n", miniWord);
00066         Mini::print_mem( binaryMiniWord, (*size_mem_mpz));
00067         std::cout << " mpz_size: " << (*size_mem_mpz) << std::endl;
00068         std::cout << " k:        " << k << std::endl;
00069         std::cout << " noteOff:  " << noteOffValue << std::endl << std::endl;
00070 }
00071 
00072 //***************************************************************
00073 void Mini::ksub_rank ( int k, int* a, mpz_t rank )
00074 {
00075   int i, j;
00076         int first = 0;
00077   mpz_t iprod;
00078   mpz_init(iprod);
00079 
00080         // check if it is the first chord [0], [0][1], [0][1][2]
00081         for(i=1;i<=k;i++)
00082         {
00083                 // check if it is first arrray
00084                 if(a[i-1] == (i-1))
00085                         first = 1;
00086                 // check if array contains a relative note smaller 0
00087                 else if(a[i-1] < 0)
00088                 {
00089                         mpz_set_ui(rank,0);
00090                         std::cout << "Played Note smaller than start Key!" << std::endl;
00091                         return;
00092                 }
00093                 else
00094                 {
00095                         first = 0;
00096                         break;
00097                 }
00098         }
00099 
00100         // set rank to 0
00101         if(first==1)
00102                 mpz_set_ui(rank,0);
00103 
00104         // calculate rank
00105         else
00106         {
00107                 // sum up to rank
00108                 for(i=1;i<=k;i++)
00109                 {
00110                         mpz_set_ui(iprod,1);
00111 
00112                         for (j=i+1; j<=a[i-1]-1; j++)
00113                                 mpz_mul_ui(iprod,iprod,j);
00114 
00115                         for (j=1; j<=a[i-1]-i-1; j++)
00116                                 mpz_cdiv_q_ui(iprod,iprod,j);
00117 
00118                         if(a[i-1]==i) /* bug: a[i-1] == 1, modified by GR 14.05.04 */
00119                                 mpz_set_ui(iprod,0);
00120 
00121                         mpz_add(rank, rank, iprod);
00122                 }
00123 
00124                 mpz_add_ui(rank, rank, 1);
00125                 mpz_clear(iprod);
00126         }
00127   return;
00128 }
00129 
00130 //***************************************************************
00131 void Mini::ksub_unrank ( int k, int* a, mpz_t rank )
00132 {
00133         int i, ip;
00134   mpz_t jrank, iprod, tmp1;
00135 
00136   mpz_init(jrank);
00137   mpz_init(iprod);
00138   mpz_init(tmp1);
00139 
00140         // rank is 0
00141         if(mpz_cmp_ui(rank,0)==0)
00142         {
00143                 for(i=0;i<k;i++)
00144                 {
00145                         a[i] = i;
00146                 }
00147         }
00148         // rank is not 0
00149         else
00150         {
00151                 mpz_sub_ui(jrank, rank, 1);
00152 
00153                 for(i=k; 1<=i; i--)
00154                 {
00155                         ip=i-1;
00156                         mpz_set_ui(iprod,1);
00157 
00158                         for(;;)
00159                         {
00160                                 ip++;
00161                                 if(ip!=i)
00162                                 {
00163                                         mpz_mul_ui(tmp1,iprod, ip);
00164                                         mpz_cdiv_q_ui(iprod, tmp1, (ip-i));
00165                                 }
00166                                 if(mpz_cmp(jrank,iprod)<0)
00167                                         break;
00168                         }
00169 
00170                         if(ip!=i)
00171                         {
00172                                 mpz_mul_ui(tmp1, iprod, (ip-i));
00173                                 mpz_cdiv_q_ui(iprod, tmp1, ip);
00174                         }
00175 
00176                         mpz_sub(jrank, jrank, iprod);
00177                         a[i-1]=ip;
00178                 }
00179 
00180                 mpz_clear(jrank);
00181                 mpz_clear(iprod);
00182                 mpz_clear(tmp1);
00183         }
00184   return;
00185 }
00186 
00187 //*****************************************************************
00188 int Mini::get_bin_digits_mpz(mpz_t number)
00189 {
00190         int count=1;
00191         if( mpz_cmp_ui(number,1) == 0 )
00192                 return 1;
00193 
00194         mpz_fdiv_q_ui(number,number,2);
00195         while( (mpz_cmp_ui(number,0)) > 0 )
00196         {
00197                 count++;
00198                 if( mpz_cmp_ui(number,1) == 0)
00199                         return count;
00200                 mpz_fdiv_q_ui(number,number,2);
00201         }
00202         return count;
00203 }
00204 
00205 //*****************************************************************
00206 int Mini::get_bin_digits_int(int number)
00207 {
00208         int count=1;
00209         if(number==1)
00210                 return 1;
00211         while( (number=number/2)>0 )
00212                 count++;
00213         return count;
00214 }
00215 
00216 //***************************************************************
00217 void Mini::mpz_2_bin(mpz_t value, int k, int note, char* mem_pointer)
00218 {
00219         int digits_value, digits_k, digits_size, size_mem;
00220         char* location; // pointer for going thru the bin_val
00221         
00222         mpz_t value_temp, value_temp2, remainder;
00223         mpz_init(value_temp);
00224         mpz_init(value_temp2);
00225         mpz_init(remainder);
00226         mpz_set(value_temp, value);
00227         mpz_set(value_temp2, value);
00228         mpz_set_ui(remainder,0);
00229 
00230         // calculate the amount of necessary digits
00231         digits_k = get_bin_digits_int(k);
00232         digits_value = get_bin_digits_mpz(value);
00233 
00234         // caclulate size of buffer in memory
00235         size_mem = get_size_mem_mpz(value_temp2);
00236         digits_size = get_bin_digits_int(size_mem);
00237 
00238         int k_tmp = k;
00239         int size_mem_tmp = size_mem;
00240 
00241         // set to start of lowest byte
00242         location = mem_pointer + (size_mem-1);
00243 
00244         //-------------------------------------------------------------
00245         // shift CHORD CODE in memory
00246         for(int i=0;i<((size_mem-1)*8); i++)
00247         {
00248                 // fill value
00249                 if(i<digits_value)
00250                 {
00251                         mpz_mod_ui(remainder, value_temp, 2); // mod 2
00252                         if( mpz_cmp_ui(remainder,1) == 0  ) // compare remainder with 1
00253                         {
00254                                 *location = (*location) >> 1;
00255                                 *location = (*location) | 128;
00256                         }
00257                         else if( mpz_cmp_ui(remainder,0) == 0 ) // compare remainder with 0
00258                         {
00259                                 *location = (*location) >> 1;
00260                                 *location = (*location) & 127;
00261                         }
00262                         mpz_fdiv_q_ui(value_temp,value_temp,2);
00263                 }
00264                 // fill zeros
00265                 else
00266                 {
00267                                 *location = (*location) >> 1;
00268                                 *location = (*location) & 127;
00269                 }
00270 
00271                 // switch to another char in memory
00272                 if(((i+1)%8)==0)
00273                         location--;
00274         }
00275 
00276         //-------------------------------------------------------------
00277         // shift VOICE CODE in memory
00278         for(int i=0;i<DIGITS_K_DEF;i++)
00279         {
00280                 // fill value
00281                 if(i<digits_k)
00282                 {
00283                         if(k_tmp%2==1)
00284                         {
00285                                 *location = (*location) >> 1; // leftshift with 0
00286                                 *location = (*location) | 128; // set to 1
00287                         }
00288                         else
00289                         {
00290                                 *location = (*location) >> 1;
00291                                 *location = (*location) & 127; // set to 0
00292                         }
00293                         k_tmp=k_tmp/2;
00294                 }
00295                 // fill zeros
00296                 else
00297                 {
00298                                 *location = (*location) >> 1;
00299                                 *location = (*location) & 127; // set to 0
00300                 }
00301         }
00302 
00303         //-------------------------------------------------------------
00304         // shift in SIZE CODE
00305         for(int i=0;i<DIGITS_SIZE_DEF;i++)
00306         {
00307                 // fill value
00308                 if(i<digits_size)
00309                 {
00310                         if((size_mem_tmp%2)==1)
00311                         {
00312                                 *location = (*location) >> 1;
00313                                 *location = (*location) | 128;
00314                         }
00315                         else
00316                         {
00317                                 *location = (*location) >> 1;
00318                                 *location = (*location) & 127;
00319                         }
00320                         size_mem_tmp = size_mem_tmp/2;
00321                 }
00322                 // fill zeros
00323                 else
00324                 {
00325                                 *location = (*location) >> 1;
00326                                 *location = (*location) & 127;
00327                 }
00328         }
00329 
00330         //------------------------------------------------------------
00331         // shift NOTE ON/OFF command in memory
00332         if(note == 1)
00333         {
00334           *location = (*location) >> 1;
00335           *location = (*location) | 128;
00336         }
00337         else if(note == 0)
00338         {
00339           *location = (*location) >> 1;
00340           *location = (*location) & 127;
00341         }
00342 }
00343 
00344 //***************************************************************
00345 void Mini::bin_2_mpz ( char* mem_pointer, int* k, mpz_t value, int* note)
00346 {
00347         mpz_set_ui(value,0);
00348         *k = 0;
00349         *note = 0;
00350 
00351         char first = mem_pointer[0];
00352 
00353         // read note on/off
00354         if(first & 128)
00355                 *note = 1;
00356         else
00357                 *note = 0;
00358 
00359         // read size
00360         int size_mem = 0;
00361         if(first & 64)
00362                 size_mem += 4;
00363         if(first & 32)
00364                 size_mem += 2;
00365         if(first & 16)
00366                 size_mem += 1;
00367 
00368         // read k
00369         if(first & 8)
00370                 *k += 8;
00371         if(first & 4)
00372                 *k += 4;
00373         if(first & 2)
00374                 *k += 2;
00375         if(first & 1)
00376                 *k += 1;
00377 
00378         // read value
00379         for(int i=0; i<size_mem-1; i++)
00380         {
00381                 char temp = mem_pointer[size_mem-1-i];
00382 
00383                 if(temp & 1)
00384                         mpz_add_ui(value, value, (int)pow(2.0, (double)(0+(i*8))));
00385                 if(temp & 2)
00386                         mpz_add_ui(value, value, (int)pow(2.0, (double)(1+(i*8))));
00387                 if(temp & 4)
00388                         mpz_add_ui(value, value, (int)pow(2.0, (double)(2+(i*8))));
00389                 if(temp & 8)
00390                         mpz_add_ui(value, value, (int)pow(2.0, (double)(3+(i*8))));
00391                 if(temp & 16)
00392                         mpz_add_ui(value, value, (int)pow(2.0, (double)(4+(i*8))));
00393                 if(temp & 32)
00394                         mpz_add_ui(value, value, (int)pow(2.0, (double)(5+(i*8))));
00395                 if(temp & 64)
00396                         mpz_add_ui(value, value, (int)pow(2.0, (double)(6+(i*8))));
00397                 if(temp & 128)
00398                         mpz_add_ui(value, value, (int)pow(2.0, (double)(7+(i*8))));
00399         }
00400 }
00401 
00402 //*****************************************************************
00403 void Mini::sort_array( int* noteArray, int size )
00404 {
00405         int pass=1, pair=1, temp=0;
00406 
00407         for(pass=1;pass<size;pass++)
00408         {
00409                 for(pair=1;pair<size;pair++)
00410                 {
00411                         if(noteArray[pair-1]>noteArray[pair])
00412                         {
00413                                 temp = noteArray[pair-1];
00414                                 noteArray[pair-1]=noteArray[pair];
00415                                 noteArray[pair]=temp;
00416                         }
00417                 }
00418         }
00419 }
00420 
00421 //*****************************************************************
00422 void Mini::print_array( int* noteArray, int size, int startKey )
00423 {
00424         for(int i=0;i<size;i++)
00425         {
00426                 std::cout << " noteArray[" << i << "]: " << noteArray[i] << 
00427                         " + startKey(" << startKey << ") = " 
00428                         << noteArray[i]+startKey << std::endl;
00429         }
00430 }
00431 
00432 //*****************************************************************
00433 void Mini::extract_size(char firstRead, int* size)
00434 {
00435         char tmp = firstRead;
00436         *size = 0;
00437         
00438         // size         
00439         if(tmp & 64)
00440                 (*size) += 4;
00441         if(tmp & 32)
00442                 (*size) += 2;
00443         if(tmp & 16)
00444                 (*size) += 1;   
00445 }
00446 
00447 //*****************************************************************
00448 void Mini::print_mem(char* mem_pointer, int size_bin)
00449 {
00450         std::cout << " content:      ";
00451         for(int i=0;i<size_bin;i++)
00452         {
00453                 char b = mem_pointer[i];
00454                 std::cout << "{ ";
00455                 for (int j=0; j<8; j++)
00456                 {
00457                         if(b & 128)
00458                                 std::cout << "1";
00459                         else
00460                                 std::cout << "0";
00461 
00462                         b = b << 1; // um eine stelle nach links shiften
00463 
00464                         // separate note on/off
00465                         if(i==0 && j==0)
00466                                 std::cout << " | ";
00467                         // separate size
00468                         if(i==0 && j==3)
00469                                 std::cout << " | ";
00470                 }
00471                 std::cout << " } ";
00472         }
00473         std::cout << std::endl;
00474 }

Generated on Mon Jun 13 22:06:59 2005 for Netmusic by  doxygen 1.4.3