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
00045 mpz_init(miniWord);
00046 mpz_init(tempWord1);
00047 mpz_init(tempWord2);
00048 mpz_set_ui(miniWord,0);
00049
00050
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
00060 binaryMiniWord = tmp;
00061
00062
00063 std::cout << DELIMITER << std::endl;
00064 Mini::print_array(noteArray, k, startKey);
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
00081 for(i=1;i<=k;i++)
00082 {
00083
00084 if(a[i-1] == (i-1))
00085 first = 1;
00086
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
00101 if(first==1)
00102 mpz_set_ui(rank,0);
00103
00104
00105 else
00106 {
00107
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)
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
00141 if(mpz_cmp_ui(rank,0)==0)
00142 {
00143 for(i=0;i<k;i++)
00144 {
00145 a[i] = i;
00146 }
00147 }
00148
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;
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
00231 digits_k = get_bin_digits_int(k);
00232 digits_value = get_bin_digits_mpz(value);
00233
00234
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
00242 location = mem_pointer + (size_mem-1);
00243
00244
00245
00246 for(int i=0;i<((size_mem-1)*8); i++)
00247 {
00248
00249 if(i<digits_value)
00250 {
00251 mpz_mod_ui(remainder, value_temp, 2);
00252 if( mpz_cmp_ui(remainder,1) == 0 )
00253 {
00254 *location = (*location) >> 1;
00255 *location = (*location) | 128;
00256 }
00257 else if( mpz_cmp_ui(remainder,0) == 0 )
00258 {
00259 *location = (*location) >> 1;
00260 *location = (*location) & 127;
00261 }
00262 mpz_fdiv_q_ui(value_temp,value_temp,2);
00263 }
00264
00265 else
00266 {
00267 *location = (*location) >> 1;
00268 *location = (*location) & 127;
00269 }
00270
00271
00272 if(((i+1)%8)==0)
00273 location--;
00274 }
00275
00276
00277
00278 for(int i=0;i<DIGITS_K_DEF;i++)
00279 {
00280
00281 if(i<digits_k)
00282 {
00283 if(k_tmp%2==1)
00284 {
00285 *location = (*location) >> 1;
00286 *location = (*location) | 128;
00287 }
00288 else
00289 {
00290 *location = (*location) >> 1;
00291 *location = (*location) & 127;
00292 }
00293 k_tmp=k_tmp/2;
00294 }
00295
00296 else
00297 {
00298 *location = (*location) >> 1;
00299 *location = (*location) & 127;
00300 }
00301 }
00302
00303
00304
00305 for(int i=0;i<DIGITS_SIZE_DEF;i++)
00306 {
00307
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
00323 else
00324 {
00325 *location = (*location) >> 1;
00326 *location = (*location) & 127;
00327 }
00328 }
00329
00330
00331
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
00354 if(first & 128)
00355 *note = 1;
00356 else
00357 *note = 0;
00358
00359
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
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
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
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;
00463
00464
00465 if(i==0 && j==0)
00466 std::cout << " | ";
00467
00468 if(i==0 && j==3)
00469 std::cout << " | ";
00470 }
00471 std::cout << " } ";
00472 }
00473 std::cout << std::endl;
00474 }