|
¡û ¤Ï¤¸¤á¤Ë
¿§¡¹¤Ê³Ú´ï¡Ê¥Ü¡¼¥«¥ë¤â´Þ¤á¤Æ¡Ë¤ò»È¤Ã¤Æ 1 ¤Ä¤Î¶Ê¤òºî¤í¤¦¤È¤¹¤ë¾ì¹ç¡¢ÉáÄ̤ϤޤºÃ±°ì³Ú´ï¤Î¤ß¤òÏ¿¤Ã¤¿¥È¥é¥Ã¥¯¤òºî¤ê¡¢¤½¤ì¤é¤ò¹çÀ®¤·¤Æ¶Ê¤Ë»Å¾å¤²¤Þ¤¹¡Ê¥ß¥Ã¥¯¥¹¥À¥¦¥ó¡Ë¡£¤½¤ÎºÝ¡¢¥È¥é¥Ã¥¯¤´¤È¤Ë²»Î̤äÄê°Ì¡Ê²»¸»¤Î°ÌÃ֡ˤòÄ´À°¤·¤¿¤ê¡¢¥¨¥Õ¥§¥¯¥È¤ò¤«¤±¤¿¤ê¤¹¤ë¤³¤È¤Çµ¤»ý¤Á¤è¤¯Ê¹¤±¤ë²»¤òºî¤ë¤³¤È¤¬½ÐÍè¤Þ¤¹¡£
¤³¤³¤Ç¤Ï¤½¤ó¤Ê¤Ë¤Á¤ã¤ó¤È¤·¤¿Êª¤Ç¤Ï¤Ê¤¯¡¢¡Ö2 ¤Ä¤Î²»¸»¤òñ½ã¤Ë¹çÀ®¤·¤Æ 1 ¤Ä¤Î²»¤òºî¤ê½Ð¤¹¡×ÄãÀǽ¥ß¥¥µ¤ò½ñ¤¤¤Æ¤ß¤¿¤¤¤È»×¤¤¤Þ¤¹¡£¤Á¤ã¤ó¤È¤·¤¿Êª¤òºî¤ë¤Ë¤Ï¡¢Ãø¼Ô¤Î²»¤Ë´Ø¤¹¤ëÃ챤¬Â¤ê¤Ê¤µ²á¤®¤Þ¤¹¤Î¤Ç¡°¡°¡¨
²¿¸Î¤³¤ì¤ò½ñ¤³¤¦¤È»×¤Ã¤¿¤«¤È¸À¤¤¤Þ¤¹¤È¡¢°ÊÁ° Linux® ¤ÇÆ°¤¯¥²¡¼¥à¤òºî¤í¤¦¤È¤·¤¿»þ¤Ë¸ú²Ì²»¤ò½Ð¤½¤¦¤È¤·¤¿¤Î¤Ç¤¹¤¬¡¢ÀΤΥµ¥¦¥ó¥É¥É¥é¥¤¥Ð¤ÏÊ£¿ô¤Î²»¤òƱ»þ¤Ë¥Ç¥Ð¥¤¥¹¥Õ¥¡¥¤¥ë¤Ë½ñ¤¹þ¤ó¤Ç¤âƱ»þ¤ËÌĤ餷¤Æ¤¯¤ì¤Ê¤«¤Ã¤¿¤«¤é¤Ç¤¹¡£²¿»þ¤À¤Ã¤¿¤«¤Ï˺¤ì¤Þ¤·¤¿¤¬¡¢¤½¤Î¤¦¤ÁƱ»þ¤Ë½ñ¤¹þ¤á¤Ð¥É¥é¥¤¥Ð¤ÎÊý¤Ç¹çÀ®¤·¤Æ¤¯¤ì¤ëÍͤˤʤ俤Ȥ¤¤¦µ²±¤¬¤«¤¹¤«¤Ë¤¢¤ë¤Î¤Ç¤¹¤¬¡¢¥¿¥¤¥ß¥ó¥°¤ÎÀ©¸æ¤¬³Î¼Â¤Ç¤Ï¤Ê¤¤¤³¤È¤ä¥É¥é¥¤¥Ð¤ÎÆ°ºî¤òÄ´¤Ù¤ë¤Î¤¬ÌÌÅݤÀ¤Ã¤¿¤Î¤Ç¡¢·ë¶É¼«Á°¤Ç¹çÀ®¤¹¤ë¥é¥¤¥Ö¥é¥ê¤òºî¤ê¤Þ¤·¤¿¡£
¤½¤Î»þ¤Î·Ð¸³¤ò»Ä¤¹¤È¤¤¤¦°ÕÌ£¤Ç¡¢ËÜ¥Ú¡¼¥¸¤ò½ñ¤¤¤Æ¤ß¤Þ¤·¤¿¡£
¡û ¥µ¥ó¥×¥ë¥×¥í¥°¥é¥à
»ØÄꤷ¤¿ 2 ¤Ä¤Î WAVE ¥Õ¥¡¥¤¥ë¤Ë¤Ä¤¤¤Æ¡¢ÊÒÊý¤Î¤ß¤òºÆÀ¸¤·¤¿¤ê 2 ¤Ä¤ò¤·¹ç¤ï¤»¤ÆƱ»þºÆÀ¸¤¹¤ë¥µ¥ó¥×¥ë¥×¥í¥°¥é¥à mix.c ¤Ç¤¹¡£¤Ï¤¸¤á¤Ë ¤Î¥Ú¡¼¥¸¤«¤é¡¢Á´¤Æ¤Î¥µ¥ó¥×¥ë¥×¥í¥°¥é¥à¤ò¸Ç¤á¤¿ tar ¥Ü¡¼¥ë¤ò¥À¥¦¥ó¥í¡¼¥É¤¹¤ë¤³¤È¤â¤Ç¤¤Þ¤¹¡£
pthread ¤ò»È¤Ã¤Æ¤¤¤Þ¤¹¤Î¤Ç
gcc -o mix mix.c -lpthread
¤ÎÍÍ¤Ë -lpthread ¥ª¥×¥·¥ç¥ó¤òÉÕ¤±¤Æ¥³¥ó¥Ñ¥¤¥ë¤·¤Þ¤¹¡£
°ú¿ô¤Ë 2 ¤Ä¤Î WAVE ¥Õ¥¡¥¤¥ë¤ÎÀäÂХѥ¹¤ò»ØÄꤷ¤Æ¼Â¹Ô¤¹¤ë¤È¡¢°Ê²¼¤ÎÍͤʥá¥Ë¥å¡¼¤¬É½¼¨¤µ¤ì¤Þ¤¹¡£ÈÖ¹æ¤òÆþÎϤ·¤Æ Enter ¤ò²¡¤¹¤È¡¢»ØÄꤷ¤¿ÆâÍƤ˽¾¤Ã¤Æ WAVE ¥Õ¥¡¥¤¥ë¤òºÆÀ¸¤·¤Þ¤¹¡£
Select menu ... 1. Play first specified wave file only. 2. Play second specified wave file only. 3. Play both wave files simultaneously. 4. Stop playing. 99. Exit. Command ?
»ØÄê¤Ç¤¤ë WAVE ¥Õ¥¡¥¤¥ë¤Ï
- PCM ¥Õ¥©¡¼¥Þ¥Ã¥È
- Î̻Ҳ½¥Ó¥Ã¥È¿ô 16 ¥Ó¥Ã¥È
- 1 ¥Á¥ã¥ó¥Í¥ë
¤Ç¤¹¡£¤Þ¤¿¡¢2 ¤Ä¤Î WAVE ¥Õ¥¡¥¤¥ë¤ÏƱ¤¸¥µ¥ó¥×¥ê¥ó¥°¥ì¡¼¥È¤Ç¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó¡£
--- mix.c ---
1 #include <fcntl.h> 2 #include <limits.h> 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include <string.h> 6 #include <linux/soundcard.h> 7 #include <pthread.h> 8 #include <sys/ioctl.h> 9 #include <unistd.h> 10 11 12 #define COMMAND_STOP 0 13 #define COMMAND_PLAY_FIRST 1 14 #define COMMAND_PLAY_SECOND 2 15 #define COMMAND_PLAY_BOTH 3 16 #define COMMAND_EXIT 4 17 18 #define BUFSIZE 4096 19 20 21 /* WAVE ¥Õ¥¡¥¤¥ë¤Î¾ðÊó¤ò³ÊǼ¤¹¤ë¹½Â¤ÂÎ */ 22 typedef struct { 23 FILE* fp; /* ¥Õ¥¡¥¤¥ë¹½Â¤ÂÎ */ 24 short is_pcm; /* PCM ¥Õ¥©¡¼¥Þ¥Ã¥È¤Î¾ì¹ç¤Ï 1¡¢¤½¤ì°Ê³°¤Ï 0 */ 25 short channel; /* ¥â¥Î¥é¥ë¤Î¾ì¹ç¤Ï 1¡¢¥¹¥Æ¥ì¥ª¤Î¾ì¹ç¤Ï 2 */ 26 int rate; /* ¥µ¥ó¥×¥ê¥ó¥°¼þÇÈ¿ô */ 27 short bits; /* Î̻Ҳ½¥Ó¥Ã¥È¿ô */ 28 long offset; /* ¥Õ¥¡¥¤¥ëÀèƬ¤«¤é PCM ¥Ç¡¼¥¿¤Þ¤Ç¤Î¥ª¥Õ¥»¥Ã¥È */ 29 int len; /* PCM ¥Ç¡¼¥¿Éô¤ÎŤµ */ 30 int current; /* ¸½ºß¤ÎºÆÀ¸°ÌÃÖ */ 31 } 32 WAVE; 33 34 35 /* ºÆÀ¸¤ËɬÍפʥǡ¼¥¿¤ò¤Þ¤È¤á¤¿¹½Â¤ÂÎ */ 36 typedef struct { 37 pthread_t thread_id; 38 int command; 39 int dsp; 40 WAVE wave[2]; 41 short buffer[ BUFSIZE / sizeof( short ) ]; 42 } 43 Context; 44 45 static Context context; 46 47 48 static int read_file( char** fnames, WAVE* wave ); 49 static int setup_dsp( int* fd, WAVE* wave ); 50 static void show_menu( void ); 51 static void* play_thread( void* param ); 52 static void fill_buffer( short* dst, WAVE* wave ); 53 static void mix( short* dst, WAVE* wave ); 54 static void shutdown(); 55 56 57 int 58 main( int argc, char** argv ) 59 { 60 pthread_attr_t attr; 61 int ret; 62 63 if ( argc != 3 ) { 64 fprintf( stderr, "usage : ./wave filename1 filename2\n" ); 65 return 1; 66 } 67 68 if ( read_file( &( argv[1] ), &( context.wave[0] ) ) != 0 ) { 69 fprintf( stderr, "Failed to read wave files.\n" ); 70 return 1; 71 } 72 73 if ( setup_dsp( &( context.dsp ), &( context.wave[0] ) ) != 0 ) { 74 fprintf( stderr, "Failed to setup /dev/dsp.\n" ); 75 return 1; 76 } 77 78 pthread_attr_init( &attr ); 79 pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_JOINABLE ); 80 81 ret = pthread_create( &( context.thread_id ), &attr, 82 play_thread, ( void* )( &context ) ); 83 84 pthread_attr_destroy( &attr ); 85 86 if ( ret ) { 87 fprintf( stderr, "Failed to create thread.\n" ); 88 shutdown(); 89 return 1; 90 } 91 92 show_menu(); 93 pthread_join( context.thread_id, NULL ); 94 shutdown(); 95 96 return 0; 97 } 98 99 100 static int 101 read_file( char** fnames, WAVE* wave ) 102 { 103 char buf[32]; 104 int len; 105 int i; 106 107 for ( i = 0; i < 2; i ++ ) { 108 if ( ( wave[i].fp = fopen( fnames[i], "r" ) ) == NULL ) { 109 fprintf( stderr, "Failed to open %s\n", fnames[i] ); 110 goto err; 111 } 112 113 /* 114 * ÀèƬ 4 ¥Ð¥¤¥È¤¬ "RIFF" ¤Ç¤¢¤ë¤³¤È¤ò³Îǧ 115 * ¹¹¤Ë 4 ¥Ð¥¤¥È¥¹¥¥Ã¥×¤·¤Æ¤ª¤¯ 116 */ 117 fread( buf, 8, 1, wave[i].fp ); 118 119 if ( strncmp( buf, "RIFF", 4 ) != 0 ) { 120 fprintf( stderr, "Specified file is not RIFF file.\n" ); 121 goto err; 122 } 123 124 125 /* ¼¡¤Î 4 ¥Ð¥¤¥È¤¬ "WAVE" ¤Ç¤¢¤ë¤³¤È¤ò³Îǧ */ 126 fread( buf, 4, 1, wave[i].fp ); 127 128 if ( strncmp( buf, "WAVE", 4 ) != 0 ) { 129 fprintf( stderr, "Specified file is not WAVE file.\n" ); 130 goto err; 131 } 132 133 /* fmt ¥Á¥ã¥ó¥¯¤òõ¤¹ */ 134 while ( 1 ) { 135 fread( buf, 8, 1, wave[i].fp ); 136 len = *( int* )( &buf[4] ); 137 138 if ( strncmp( buf, "fmt ", 4 ) != 0 ) { 139 if ( fseek( wave[i].fp, len, SEEK_CUR ) == -1 ) { 140 fprintf( stderr, "Failed to find fmt.\n" ); 141 goto err; 142 } 143 } 144 else { 145 break; 146 } 147 } 148 149 fread( buf, len, 1, wave[i].fp ); 150 151 wave[i].is_pcm = *( ( short* )( &buf[0] ) ); 152 wave[i].channel = *( ( short* )( &buf[2] ) ); 153 wave[i].rate = *( ( int* )( &buf[4] ) ); 154 wave[i].bits = *( ( short* )( &buf[14] ) ); 155 156 /* 157 * PCM / 16 bits / Monoral °Ê³°¤Î WAVE ¥Ç¡¼¥¿¤Ë¤Ä¤¤¤Æ¤Ï 158 * ËÜ¥×¥í¥°¥é¥à¤Ç¤ÏÂоݳ° 159 */ 160 if ( wave[i].is_pcm != 1 ) { 161 fprintf( stderr, "WAVE file must be PCM format.\n" ); 162 goto err; 163 } 164 165 if ( wave[i].bits != 16 ) { 166 fprintf( stderr, "WAVE file must be 16 bits .\n" ); 167 goto err; 168 } 169 170 if ( wave[i].channel != 1 ) { 171 fprintf( stderr, "WAVE file must be monoral.\n" ); 172 goto err; 173 } 174 175 /* data ¥Á¥ã¥ó¥¯¤òõ¤¹ */ 176 while ( 1 ) { 177 fread( buf, 8, 1, wave[i].fp ); 178 len = *( int* )( &buf[4] ); 179 180 if ( strncmp( buf, "data", 4 ) != 0 ) { 181 if ( fseek( wave[i].fp, len, SEEK_CUR ) == -1 ) { 182 fprintf( stderr, "Failed to find data.\n" ); 183 goto err; 184 } 185 } 186 else { 187 break; 188 } 189 } 190 191 wave[i].len = len; 192 193 if ( ( wave[i].offset = ftell( wave[i].fp ) ) == -1 ) { 194 fprintf( stderr, "Failed to find offset of PCM data.\n" ); 195 goto err; 196 } 197 198 printf( "\n" ); 199 printf( "WAVE file format of %s:\n", fnames[i] ); 200 printf( " rate = %d\n", wave[i].rate ); 201 printf( " channel = %d\n", wave[i].channel ); 202 printf( " bits = %d\n", wave[i].bits ); 203 printf( " offsets = %ld\n", wave[i].offset ); 204 printf( " length = %d\n", wave[i].len ); 205 printf( "\n" ); 206 } 207 208 if ( wave[0].rate != wave[1].rate ) { 209 fprintf( stderr, "Specified 2 WAVE files " 210 "must have the same sampling rate.\n" ); 211 goto err; 212 } 213 214 return 0; 215 216 err: 217 if ( wave[0].fp != NULL ) { 218 fclose( wave[0].fp ); 219 } 220 221 if ( wave[1].fp != NULL ) { 222 fclose( wave[1].fp ); 223 } 224 225 return 1; 226 } 227 228 229 static int 230 setup_dsp( int* dsp, WAVE* wave ) 231 { 232 int fragment = 0x0004000c; /* size = 4096 bytes, num of fragments = 4. */ 233 int format = AFMT_S16_LE; 234 int rate; 235 int channel; 236 237 rate = ( int )wave[0].rate; 238 channel = ( int )wave[0].channel; 239 240 if ( ( *dsp = open( "/dev/dsp", O_WRONLY ) ) == -1 ) { 241 perror( "open()" ); 242 return 1; 243 } 244 245 if ( ioctl( *dsp, SNDCTL_DSP_SETFRAGMENT, &fragment ) == -1 ) { 246 perror( "ioctl( SNDCTL_DSP_SETFRAGMENT )" ); 247 close( *dsp ); 248 return 1; 249 } 250 251 if ( ioctl( *dsp, SNDCTL_DSP_SETFMT, &format ) == -1 ) { 252 perror( "ioctl( SNDCTL_DSP_SETFMT )" ); 253 close( *dsp ); 254 return 1; 255 } 256 257 if ( ioctl( *dsp, SNDCTL_DSP_SPEED, &rate ) == -1 ) { 258 perror( "ioctl( SNDCTL_DSP_SPEED )" ); 259 close( *dsp ); 260 return 1; 261 } 262 263 if ( ioctl( *dsp, SNDCTL_DSP_CHANNELS, &channel ) == -1 ) { 264 perror( "ioctl( SNDCTL_DSP_CHANNELS )" ); 265 close( *dsp ); 266 return 1; 267 } 268 269 return 0; 270 } 271 272 273 static void 274 show_menu( void ) 275 { 276 char line[4]; 277 int command; 278 279 while ( 1 ) { 280 printf( "Select menu ...\n" ); 281 printf( " 1. Play first specified wave file only.\n" ); 282 printf( " 2. Play second specified wave file only.\n" ); 283 printf( " 3. Play both wave files simultaneously.\n" ); 284 printf( " 4. Stop playing.\n" ); 285 printf( " 99. Exit.\n" ); 286 printf( "\n" ); 287 printf( "Command ? " ); 288 289 fgets( line, sizeof( line ), stdin ); 290 sscanf( line, "%d\n", &command ); 291 292 switch ( command ) { 293 case 1: 294 context.command = COMMAND_PLAY_FIRST; 295 break; 296 case 2: 297 context.command = COMMAND_PLAY_SECOND; 298 break; 299 case 3: 300 context.command = COMMAND_PLAY_BOTH; 301 break; 302 case 4: 303 context.command = COMMAND_STOP; 304 break; 305 case 99: 306 context.command = COMMAND_EXIT; 307 return; 308 } 309 } 310 } 311 312 313 static void* 314 play_thread( void* param ) 315 { 316 Context* context = ( Context* )param; 317 318 while ( context->command != COMMAND_EXIT ) { 319 memset( ( void* )( context->buffer ), 0, BUFSIZE ); 320 321 switch ( context->command ) { 322 case COMMAND_PLAY_FIRST: 323 fill_buffer( ( void* )( context->buffer ), 324 &( context->wave[0] ) ); 325 break; 326 327 case COMMAND_PLAY_SECOND: 328 fill_buffer( ( void* )( context->buffer ), 329 &( context->wave[1] ) ); 330 break; 331 332 case COMMAND_PLAY_BOTH: 333 mix( ( void* )( context->buffer ), 334 &( context->wave[0] ) ); 335 break; 336 337 case COMMAND_STOP: 338 default: 339 break; 340 } 341 342 write( context->dsp, ( void* )( context->buffer ), BUFSIZE ); 343 } 344 345 pthread_exit( NULL ); 346 } 347 348 349 static void 350 fill_buffer( short* dst, WAVE* wave ) 351 { 352 int copied = 0; 353 354 while ( 1 ) { 355 int src_left = wave->len - wave->current; 356 int dst_left = BUFSIZE - copied; 357 int copy_len = src_left > dst_left ? dst_left : src_left; 358 359 if ( src_left == 0 ) { 360 fseek( wave->fp, wave->offset, SEEK_SET ); 361 wave->current = 0; 362 continue; 363 } 364 365 if ( dst_left == 0 ) { 366 break; 367 } 368 369 fread( ( void* )( dst + copied / sizeof( short ) ), 370 copy_len, 1, wave->fp ); 371 wave->current += copy_len; 372 copied += copy_len; 373 } 374 } 375 376 377 #define MIN( a, b ) ( ( (a) < (b) ) ? (a) : (b) ) 378 #define MAX( a, b ) ( ( (a) > (b) ) ? (a) : (b) ) 379 380 381 static void 382 mix( short* dst, WAVE* wave ) 383 { 384 short src[ BUFSIZE ]; 385 int copied; 386 int dst_index; 387 int i; 388 int j; 389 390 for ( i = 0; i < 2; i ++ ) { 391 memset( src, 0, BUFSIZE ); 392 copied = 0; 393 394 while ( 1 ) { 395 int src_left = wave[i].len - wave[i].current; 396 int dst_left = BUFSIZE - copied; 397 int copy_len = src_left > dst_left ? dst_left : src_left; 398 399 if ( src_left == 0 ) { 400 fseek( wave[i].fp, wave[i].offset, SEEK_SET ); 401 wave[i].current = 0; 402 continue; 403 } 404 405 if ( dst_left == 0 ) { 406 break; 407 } 408 409 fread( ( void* )src, copy_len, 1, wave[i].fp ); 410 411 for ( j = 0; j < copy_len / sizeof( short ); j ++ ) { 412 dst_index = copied / sizeof( short ) + j; 413 414 if ( src[j] < 0 ) { 415 dst[ dst_index ] = ( short )MAX( 416 (int)dst[ dst_index ] + (int)src[j], 417 (int)SHRT_MIN ); 418 } 419 else { 420 dst[ dst_index ] = ( short )MIN( 421 (int)dst[ dst_index ] + (int)src[j], 422 (int)SHRT_MAX ); 423 } 424 } 425 426 wave[i].current += copy_len; 427 copied += copy_len; 428 } 429 } 430 } 431 432 433 static void 434 shutdown( void ) 435 { 436 fclose( context.wave[0].fp ); 437 fclose( context.wave[1].fp ); 438 close( context.dsp ); 439 } 440 441 442 /* End of mix.c */
¡û ¥µ¥ó¥×¥ë¥×¥í¥°¥é¥à¤ÎÀâÌÀ
¤Ç¤Ï¡¢¥µ¥ó¥×¥ë¥×¥í¥°¥é¥à¤Ë¤Ä¤¤¤ÆÀâÌÀ¤·¤Æ¤¤¤¤Þ¤¹¡£
- 7 ¹ÔÌÜ
WAVE ¥Õ¥¡¥¤¥ëºÆÀ¸¤òÊÌ¥¹¥ì¥Ã¥É¤Ç¹Ô¤¦¤¿¤á¤Ë pthread ¤ò»È¤¤¤Þ¤¹¡£¤½¤Î¤¿¤á pthread.h ¤ò¤³¤³¤Ç¥¤¥ó¥¯¥ë¡¼¥É¤·¤Æ¤¤¤Þ¤¹¡£
- 21 ¡Á 32 ¹ÔÌÜ
WAVE ¥Õ¥¡¥¤¥ë¾ðÊó¤ò³ÊǼ¤¹¤ë¤¿¤á¤Î¹½Â¤ÂΤòÄêµÁ¤·¤Æ¤¤¤Þ¤¹¡£LECTURE 10 WAVE ¥Õ¥¡¥¤¥ë¤òºÆÀ¸¤¹¤ë ¤Î¥µ¥ó¥×¥ë¥×¥í¥°¥é¥à¤ÇÄêµÁ¤·¤Æ¤¤¤ë¹½Â¤ÂΤˡ¢¸½ºß¤ÎºÆÀ¸°ÌÃÖ¤òɽ¤¹ current ¥á¥ó¥Ð¤òÄɲä·¤¿¤À¤±¤Ç¤¹¡£²»¤ò²Ã»»¤¹¤ëºÝ¤Î»ÏÅÀ¤È¤·¤Æ»ÈÍѤ·¤Þ¤¹¡£
- 35 ¡Á 45 ¹ÔÌÜ
WAVE ¥Õ¥¡¥¤¥ëºÆÀ¸¥¹¥ì¥Ã¥É¤Ç»ÈÍѤ¹¤ëÊÑ¿ô¤ò¡¢°ì¤Ä¤Î¹½Â¤ÂΤˤޤȤá¤ÆÄêµÁ¤·¤Æ¤¤¤Þ¤¹¡£¤½¤·¤Æ¥Õ¥¡¥¤¥ë¥¹¥³¡¼¥×¤ò»ý¤Ä context ÊÑ¿ô¤òÀë¸À¤·¤Æ¤¤¤Þ¤¹¡£
- 57 ¡Á 97 ¹ÔÌÜ ( main() )
mix.c ¤Î main ´Ø¿ô¤Ç¤¹¡£³Æ½èÍý¤Ë¤Ä¤¤¤Æ°Ê²¼¤ÇÀâÌÀ¤·¤Æ¤¤¤¤Þ¤¹¡£
- 68 ¡Á 76 ¹ÔÌÜ
68 ¡Á 71 ¹ÔÌܤǡ¢»ØÄꤵ¤ì¤¿ 2 ¤Ä¤Î WAVE ¥Õ¥¡¥¤¥ë¤òÆɤ߹þ¤à¼«ºî´Ø¿ô read_file() ¤ò¼Â¹Ô¤·¤Æ¤¤¤Þ¤¹¡£¤½¤Î¸å 73 ¡Á 76 ¹ÔÌܤǡ¢¼«ºî´Ø¿ô setup_dsp() ¤ò¼Â¹Ô¤·¡¢/dev/dsp ¤Î½é´ü²½¤ò¹Ô¤Ã¤Æ¤¤¤Þ¤¹¡£¤¤¤º¤ì¤â¾ÜºÙ¤Ï¸åÄøÀâÌÀ¤·¤Þ¤¹¡£
- 78 ¡Á 90 ¹ÔÌÜ
¤³¤³¤Ç¤Ï¡¢WAVE ¥Õ¥¡¥¤¥ëºÆÀ¸¥¹¥ì¥Ã¥É¤ÎÀ¸À®¡¿¼Â¹Ô³«»Ï¤ò¹Ô¤Ã¤Æ¤¤¤Þ¤¹¡£81 ¹ÔÌܤΠpthread_create() ¤Ç¡¢WAVE ¥Õ¥¡¥¤¥ëºÆÀ¸¥¹¥ì¥Ã¥É¤òÀ¸À®¤·¤Þ¤¹¡£À¸À®¤µ¤ì¤¿¥¹¥ì¥Ã¥É¤Ï¼«Æ°Åª¤Ë¼Â¹Ô³«»Ï¤µ¤ì¤Þ¤¹¡£
int pthread_create( pthread_t* thread, pthread_attr_t* attr, void* ( *start_routine )( void* ), void* arg ); thread : À¸À®¤µ¤ì¤¿¥¹¥ì¥Ã¥É ID ¤¬³ÊǼ¤µ¤ì¤ë attr : ¥¹¥ì¥Ã¥É¤ËÀßÄꤹ¤ë°À¤ò»ØÄê start_routine : ¥¹¥ì¥Ã¥É¤Î¼Â¹Ô´Ø¿ô arg : start_routine ¼Â¹Ô»þ¤Ë°ú¿ô¤ËÅϤµ¤ì¤ë¥Ý¥¤¥ó¥¿
¥¹¥ì¥Ã¥ÉÀ¸À®¤ËÀ®¸ù¤·¤¿¾ì¹ç¤Ï 0 ¤ò¡¢¼ºÇÔ¤·¤¿¾ì¹ç¤Ï EAGAIN ¤òÊÖ¤·¤Þ¤¹¡£ËÜ¥µ¥ó¥×¥ë¤Ç¤Ï play_thread() ¤È¤¤¤¦¼«ºî´Ø¿ô¤ò¥¹¥ì¥Ã¥É¤Î¼Â¹Ô´Ø¿ô¤Ë»ØÄꤷ¡¢Á°½Ò¤Î context ÊÑ¿ô¤ò°ú¿ô¤ËÅϤ¹Íͤ˻ØÄꤷ¤Æ¤¤¤Þ¤¹¡£
pthread_create() ¤Î attr ¤Ë NULL ¤ò»ØÄꤷ¤¿¾ì¹ç¡¢À¸À®¤µ¤ì¤¿¥¹¥ì¥Ã¥É¤Î½ªÎ»¤òÊÌ¥¹¥ì¥Ã¥É¤«¤é pthread_join() ¤Ë¤ÆÂԤĤ³¤È¤¬½ÐÍè¤Þ¤¹¡£¤³¤³¤Ç¤Ï NULL ¤ò»ØÄꤻ¤º¡¢Æ±¤¸ÆâÍƤò pthread_attr_setdetachstate() ¤ò»È¤Ã¤ÆÌÀ¼¨Åª¤Ë»ØÄꤷ¤Æ¤¤¤Þ¤¹¡£
int pthread_attr_setdetachstate( pthread_attr_t* attr, int detachstate ); attr : °À¤ò³ÊǼ¤¹¤ë pthread_attr_t ·¿ÊÑ¿ô detachstate : PTHREAD_CREATE_JOINABLE (pthread_join() ¤ÇÂÔµ¡²Äǽ) ¤« PTHREAD_CREATE_DETACHED (pthread_join() ¤ÇÂÔµ¡ÉÔ²Ä)
À®¸ù¤·¤¿¾ì¹ç¤Ï 0 ¤ò¡¢¼ºÇÔ¤·¤¿¾ì¹ç¤Ï EINVAL ¤òÊÖ¤·¤Þ¤¹¡£¤Þ¤¿¡¢pthread_attr_t ·¿ÊÑ¿ô¤Ï pthread_attr_init() / pthread_attr_destroy() ¤ò»È¤Ã¤Æ½é´ü²½¡¿²òÊü¤ò¹Ô¤¦É¬Íפ¬¤¢¤ê¤Þ¤¹¡£
int pthread_attr_init( pthread_attr_t* attr ); int pthread_attr_destroy( pthread_attr_t* attr );
- 92 ¡Á 94 ¹ÔÌÜ
main() ¤ò¼Â¹Ô¤·¤Æ¤¤¤ë¥¹¥ì¥Ã¥É¤Ç¤Ï¡¢¼«ºî´Ø¿ô¤Î show_menu() ¤Ë¤è¤Ã¤Æ¥á¥Ë¥å¡¼É½¼¨¡¿¥æ¡¼¥¶ÆþÎϤμèÆÀ¤ò¹Ô¤¤¤Þ¤¹¡£show_menu() ¤¬½ªÎ»¤·¤¿¡Ê¥æ¡¼¥¶¤¬½ªÎ»¤ò»Ø¼¨¤·¤¿¡Ë¾ì¹ç¤Ï¡¢pthread_join() ¤Ë¤Æ WAVE ºÆÀ¸¥¹¥ì¥Ã¥É¤Î½ªÎ»¤òÂÔµ¡¤·¤¿¾å¤Ç¡¢¼«ºî´Ø¿ô¤Î shutdown() ¤ò¼Â¹Ô¤·¤Æ /dev/dsp Åù¤Î¥ê¥½¡¼¥¹¤ò²òÊü¤·¤Æ¤¤¤Þ¤¹¡£
- 100 ¡Á 226 ¹ÔÌÜ ( read_file() )
»ØÄꤵ¤ì¤¿ 2 ¤Ä¤Î WAVE ¥Õ¥¡¥¤¥ë¤ÎÆɤ߹þ¤ß¤ò¹Ô¤¤¤Þ¤¹¡£ÆâÍƤϤۤȤó¤É LECTURE 10 WAVE ¥Õ¥¡¥¤¥ë¤òºÆÀ¸¤¹¤ë ¤Î¥µ¥ó¥×¥ë¥×¥í¥°¥é¥à wave.c ¤Î wave_read_file() ¤ÈƱ¤¸¤Ç¤¹¤Î¤Ç¡¢¶ñÂÎŪ¤ÊÆɤ߹þ¤ß½èÍý¤Ë¤Ä¤¤¤Æ¤Ï¤½¤Á¤é¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£Äɲûö¹à¤È¤·¤Æ¡¢156 ¡Á 173 ¹ÔÌÜ¤Ë¤Æ PCM / 16 bits / Monoral ¤Î WAVE ¥Õ¥¡¥¤¥ë¤Ç¤¢¤ë¤«¤É¤¦¤«¤ò³Îǧ¤·¡¢¤½¤¦¤Ç¤Ê¤±¤ì¤Ð½èÍý¼ºÇԤȤ·¤Æ¤¤¤Þ¤¹¡£¤Þ¤¿¡¢208 ¡Á 212 ¹ÔÌܤˤơ¢Æɤ߹þ¤ó¤À 2 ¤Ä¤Î WAVE ¥Õ¥¡¥¤¥ë¤Î¥µ¥ó¥×¥ê¥ó¥°¥ì¡¼¥È¤¬°ìÃפ·¤Ê¤¤¾ì¹ç¤â½èÍý¼ºÇԤȤ·¤Æ¤¤¤Þ¤¹¡£
- 229 ¡Á 270 ¹ÔÌÜ ( setup_dsp() )
¤³¤ì¤Þ¤Ç¤Î¥µ¥ó¥×¥ë¥×¥í¥°¥é¥à¤ÈƱ¤¸ÍÍ¤Ë ioctl() ¤Ç /dev/dsp ¤ÎÀßÄê¤ò¹Ô¤Ã¤Æ¤¤¤Þ¤¹¡£LECTURE 10 WAVE ¥Õ¥¡¥¤¥ë¤òºÆÀ¸¤¹¤ë ¤Î¥µ¥ó¥×¥ë¥×¥í¥°¥é¥à wave.c ¤È°Û¤Ê¤ê¡¢245 ¡Á 249 ¹ÔÌܤΠioctl( SNDCTL_DSP_SETFRAGMENT ) ¤Ç¥Õ¥é¥°¥á¥ó¥È¤ÎÀßÄê¤ò¹Ô¤Ã¤Æ¤¤¤Þ¤¹¡£ÀßÄꤷ¤Æ¤¤¤ëÃÍ¤Ï 232 ¹ÔÌܤΠ0x0004000c ¤Ç¤¹¤¬¡¢¤³¤ì¤Ï¥Õ¥é¥°¥á¥ó¥È¤Î¥µ¥¤¥º¤ò 4096 ¥Ð¥¤¥È¤È¤·¡¢¥Õ¥é¥°¥á¥ó¥È¿ô¤ò 4 ¤È¤¹¤ë¡¢¤È¤¤¤¦°ÕÌ£¤Ç¤¹( LECTURE 5 ¥ê¥¢¥ë¥¿¥¤¥àÀ¤ò¹Íθ¤¹¤ë ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤ )¡£
- 273 ¡Á 310 ¹ÔÌÜ ( show_menu() )
main() ¤Î¼Â¹Ô¥¹¥ì¥Ã¥É¤Ë¤Æ¡¢¥æ¡¼¥¶ÆþÎϤò¼èÆÀ¤¹¤ë¤¿¤á¤Î¥á¥Ë¥å¡¼¤òɽ¼¨¤·¤Þ¤¹¡£¤½¤·¤ÆÆþÎϤ˱þ¤¸¤Æ¡¢¥Õ¥¡¥¤¥ëËÁƬ¤ÇÄêµÁ¤·¤Æ¤¢¤ë¥Þ¥¯¥í COMMAND_XXXXX ¤ò WAVE ºÆÀ¸¥¹¥ì¥Ã¥ÉÍѤΠcontext ÊÑ¿ô¤ËÀßÄꤷ¤Þ¤¹¡£¥æ¡¼¥¶¤¬ 99 ¤òÆþÎϤ¹¤ë¤È¡¢¥ë¡¼¥×¤òÈ´¤±¤Æ´Ø¿ô¤¬½ªÎ»¤·¤Þ¤¹¡£
- 313 ¡Á 346 ¹ÔÌÜ ( play_thread() )
WAVE ¥Õ¥¡¥¤¥ëºÆÀ¸¥¹¥ì¥Ã¥É¤Î¼Â¹Ô´Ø¿ô¤Ç¤¹¡£¥ë¡¼¥×½èÍý¤Ç¤Ï¤Þ¤ººÆÀ¸ÍѥХåե¡¤ò½é´ü²½¤·¡¢¥æ¡¼¥¶»ØÄê¤Î¥³¥Þ¥ó¥É¤Ë±þ¤¸¤Æ½èÍý¤ò¹Ô¤¤¤Þ¤¹¡£322 ¡Á 325 ¹ÔÌܤǤϡ¢ºÇ½é¤Ë»ØÄꤷ¤¿ WAVE ¥Õ¥¡¥¤¥ë¤Î¥Ç¡¼¥¿¤ò¼«ºî´Ø¿ô fill_buffer() ¤ò»È¤Ã¤ÆºÆÀ¸ÍѥХåե¡¤ËžÁ÷¤·¤Þ¤¹¡£327 ¡Á 330 ¹ÔÌܤǤϡ¢2 ÈÖÌܤ˻ØÄꤷ¤¿ WAVE ¥Õ¥¡¥¤¥ë¤Ë¤Ä¤¤¤ÆƱÍÍ¤Ë fill_buffer() ¤ò»È¤Ã¤ÆºÆÀ¸ÍѥХåե¡¤ËžÁ÷¤·¤Þ¤¹¡£fill_buffer() ¤Ë¤Ä¤¤¤Æ¤Ï¸åÄøÀâÌÀ¤·¤Þ¤¹¡£332 ¡Á 335 ¹ÔÌܤϡ¢2 ¤Ä¤Î WAVE ¥Õ¥¡¥¤¥ë¤ò¼«ºî´Ø¿ô mix() ¤Ç²Ã»»¤·¤¿·ë²Ì¤òºÆÀ¸ÍѥХåե¡¤ËžÁ÷¤·¤Þ¤¹¡£mix() ¤Ë¤Ä¤¤¤Æ¤â¸åÄøÀâÌÀ¤·¤Þ¤¹¡£
ºÆÀ¸ÍѥХåե¡¤ÎÆâÍƤò¹½ÃÛ¤·¤¿¸å¡¢342 ¹ÔÌÜ¤Ç /dev/dsp ¤ËºÆÀ¸¥Ç¡¼¥¿¤ò½ñ¤¹þ¤ó¤Ç¤¤¤Þ¤¹¡£¤Ê¤ª¡¢¥æ¡¼¥¶¤Ë¤è¤Ã¤Æ COMMAND_STOP ¤¬»ØÄꤵ¤ì¤Æ¤¤¤ë¾ì¹ç¤â¡¢Ìµ²»¾õÂ֤Υǡ¼¥¿¤ò½ñ¤¹þ¤ó¤Ç¤¤¤Þ¤¹¡£
¥æ¡¼¥¶¤Ë¤è¤Ã¤Æ COMMAND_EXIT ¤¬»ØÄꤵ¤ì¤¿¾ì¹ç¤Ï¥ë¡¼¥×¤òÈ´¤±¤Æ¡¢345 ¹ÔÌܤΠpthread_exit() ¤Ç WAVE ¥Õ¥¡¥¤¥ëºÆÀ¸¥¹¥ì¥Ã¥É¤ò½ªÎ»¤·¤Æ¤¤¤Þ¤¹¡£
void pthread_exit( void* retval ); retval: ¥¹¥ì¥Ã¥É¤Î½ªÎ»¥³¡¼¥É
- 349 ¡Á 374 ¹ÔÌÜ ( fill_buffer() )
»ØÄê¥Ð¥Ã¥Õ¥¡ ( dst ) ¤Ë WAVE ¥Õ¥¡¥¤¥ë¥Ç¡¼¥¿¤òžÁ÷¤·¤Þ¤¹¡£
WAVE ¥Õ¥¡¥¤¥ë¥Ç¡¼¥¿¤ÎžÁ÷³«»Ï°ÌÃÖ¤Ï wave->current ¤Ç»²¾È¤Ç¤¤Þ¤¹¡£355 ¡Á 357 ¹ÔÌܤǡ¢WAVE ¥Õ¥¡¥¤¥ë¥Ç¡¼¥¿¤Î»Ä¤ê¤È»ØÄê¥Ð¥Ã¥Õ¥¡¤Î»Ä¤ê¤òÈæ³Ó¤·¡¢°ìÅ٤˞Á÷¤¹¤ë¥Ð¥¤¥ÈŤò·×»»¤·¤Æ¤¤¤Þ¤¹¡£WAVE ¥Õ¥¡¥¤¥ë¥Ç¡¼¥¿¤Î½ªÃ¼¤ËÅþ㤷¤¿¾ì¹ç¤Ï¡¢359 ¡Á 363 ¹ÔÌÜ¤Ç wave->current = 0; ¤È¤¹¤ë¤³¤È¤ÇÀèƬ¤ËÌᤷ¡¢Å¾Á÷Ťη׻»¤«¤é¤ä¤êľ¤·¤Þ¤¹¡£»ØÄê¥Ð¥Ã¥Õ¥¡½ªÃ¼¤ËÅþ㤷¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢¤½¤Î»þÅÀ¤Ç½ªÎ»¤·¤Þ¤¹(365 ¡Á 367 ¹ÔÌÜ¡Ë¡£
°ìÅ٤ΞÁ÷Ťò·×»»¤·¤¿¤é¡¢369 ¹ÔÌܤΠfread() ¤Ç WAVE ¥Õ¥¡¥¤¥ë¥Ç¡¼¥¿¤ò»ØÄê¥Ð¥Ã¥Õ¥¡¤ËžÁ÷¤·¤Þ¤¹¡£fread() ¤ÎÂè°ì°ú¿ô¡ÊžÁ÷Àè»ØÄê¡Ë¤¬ dst + copied / sizeof( short ) ¤ÎÍͤˤʤäƤ¤¤ë¤Î¤Ï¡¢dst ¤¬ short* ¤Ç¤¢¤ë¤¿¤á¥¢¥É¥ì¥¹¤¬ sizeof( short ) ¤º¤ÄÁýʬ¤µ¤ì¤Æ¤·¤Þ¤¦¤«¤é¤Ç¤¹¡£
- 377 ¡Á 378 ¹ÔÌÜ ( MIN(), MAX() )
mix() ¤Ç»ÈÍѤ¹¤ë¥Þ¥¯¥í¤Ç¤¹¡£MIN() ¤Ï¾®¤µ¤¤Êý¤ÎÃͤò¡¢MAX() ¤ÏÂ礤¤Êý¤ÎÃͤòÊÖ¤·¤Þ¤¹¡£
- 381 ¡Á 430 ¹ÔÌÜ ( mix() )
2 ¤Ä¤Î WAVE ¥Õ¥¡¥¤¥ë¥Ç¡¼¥¿¤Î²Ã»»¤ò¹Ô¤¤¤Þ¤¹¡£WAVE ¥Õ¥¡¥¤¥ë¥Ç¡¼¥¿ ¢ª src¡Ê´Ø¿ôÆâ¤Î¼«Æ°ÊÑ¿ô¡Ë¢ª dst¡Ê»ØÄê¥Ð¥Ã¥Õ¥¡¡Ë¤Î½ç¤ËžÁ÷¤ò¹Ô¤¤¤Þ¤¹¡£¤Þ¤º 1 ¤Ä¤á¤Î WAVE ¥Õ¥¡¥¤¥ë¥Ç¡¼¥¿¤Ç»ØÄê¥Ð¥Ã¥Õ¥¡¤òËþ¤¿¤·¤Æ¤«¤é¡¢2 ¤Ä¤á¤Î WAVE ¥Õ¥¡¥¤¥ë¥Ç¡¼¥¿¤ò dst ¤ËžÁ÷¤·¤Æ¤¤¤Þ¤¹¡£
395 ¡Á 397 ¹ÔÌܤǰìÅ٤˞Á÷¤¹¤ë¥Ð¥¤¥ÈŤò·×»»¤·¤Æ¤¤¤Þ¤¹¡£WAVE ¥Õ¥¡¥¤¥ë¥Ç¡¼¥¿¤Î½ªÃ¼¤ËÅþ㤷¤¿¾ì¹ç¤Ï¡¢399 ¡Á 403 ¹ÔÌÜ¤Ç wave->current = 0; ¤È¤¹¤ë¤³¤È¤ÇÀèƬ¤ËÌᤷ¡¢Å¾Á÷Ťη׻»¤«¤é¤ä¤ê¤Ê¤ª¤·¤Þ¤¹¡£»ØÄê¥Ð¥Ã¥Õ¥¡½ªÃ¼¤ËÅþ㤷¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢¤½¤Î»þÅÀ¤Ç while() ¤òÈ´¤±¤Þ¤¹¡Ê405 ¡Á 407 ¹ÔÌÜ¡£¼¡¤Î WAVE ¥Õ¥¡¥¤¥ë¥Ç¡¼¥¿¤Î½èÍý¤Ë°Ü¤ë¤«¡¢²Ã»»½èÍý½ªÎ»¤Î¤¤¤º¤ì¤«¤È¤Ê¤ë¡Ë¡£
409 ¹ÔÌÜ¤Ç fread() ¤Ë¤è¤ê WAVE ¥Õ¥¡¥¤¥ë¥Ç¡¼¥¿¤ò´Ø¿ôÆâ¤Î¼«Æ°ÊÑ¿ô src ¤ËžÁ÷¤·¤Þ¤¹¡£dst ¤Ç¤Ï¤Ê¤¯¤Þ¤º src ¤ËžÁ÷¤¹¤ë¤Î¤Ï¡¢¥Õ¥¡¥¤¥ë¤«¤é°ìµ¤¤ËÆɤ߹þ¤ó¤À¾å¤Ç²Ã»»½èÍý¤ò¹Ô¤¤¤¿¤¤¤«¤é¤Ç¤¹¡£411 ¡Á 424 ¹ÔÌܤ¬¼ÂºÝ¤Î²Ã»»½èÍý¤Ç¤¹¡£´û¤Ë dst ¤Ë¤¢¤ë¥Ç¡¼¥¿¤È src ¤ò²Ã»»¤·¡¢·ë²Ì¤¬ SHRT_MIN ¤è¤ê¾®¤µ¤¯¤Ê¤ë¾ì¹ç¤Ï SHRT_MIN ¤Ë¡¢SHRT_MAX ¤è¤êÂ礤¯¤Ê¤ë¾ì¹ç¤Ï SHRT_MAX ¤Ç˰Ϥµ¤»¤Þ¤¹¡Ê16 ¥Ó¥Ã¥ÈÉä¹æÉÕ¥Õ¥©¡¼¥Þ¥Ã¥È¤Î¤¿¤á¡Ë¡£
- 433 ¡Á 439 ¹ÔÌÜ ( shutdown() )
¥ê¥½¡¼¥¹²òÊü½èÍý¤Ç¤¹¡£2 ¤Ä¤Î WAVE ¥Õ¥¡¥¤¥ë¤Î¥Õ¥¡¥¤¥ë¥Ý¥¤¥ó¥¿¤ò²òÊü¤·¡¢/dev/dsp ¤â²òÊü¤·¤Æ¤¤¤Þ¤¹¡£
°Ê¾å¤Ç mix.c ¤ÎÀâÌÀ¤Ï½ª¤ï¤ê¤Ç¤¹¡£