LECTURE 12 Ê£¿ô¤Î²»¤ò­¤¹Ã±½ã¥ß¥­¥µ

¡û ¤Ï¤¸¤á¤Ë

¿§¡¹¤Ê³Ú´ï¡Ê¥Ü¡¼¥«¥ë¤â´Þ¤á¤Æ¡Ë¤ò»È¤Ã¤Æ 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 ¤ÎÀâÌÀ¤Ï½ª¤ï¤ê¤Ç¤¹¡£