OSDN Git Service

2007-1-1 Keishi Suenaga <skeishi@yahoo.co.jp>
authorKeishi Suenaga <s_keishi@mutt.freemail.ne.jp>
Mon, 1 Jan 2007 07:27:42 +0000 (07:27 +0000)
committerKeishi Suenaga <s_keishi@mutt.freemail.ne.jp>
Mon, 1 Jan 2007 07:27:42 +0000 (07:27 +0000)
* timidity/timidity.c
  timidity/w32_a.c
  timidity/portaudio_a.c: can select optput device.

ChangeLog
timidity/portaudio_a.c
timidity/timidity.c
timidity/w32_a.c

index edc43c4..1e2c59a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2007-1-1  Keishi Suenaga <skeishi@yahoo.co.jp>
+
+       * timidity/timidity.c
+         timidity/w32_a.c
+         timidity/portaudio_a.c: can select optput device.
+         
 2007-01-01  Kentaro Sato <kentaro@ranvis.com>
 
        * timidity/playmidi.[ch], timidity/readmidi.c:
index d17516c..95bbbc6 100644 (file)
@@ -64,6 +64,8 @@
 #include "playmidi.h"
 #include "miditrace.h"
 
+int opt_pa_device_id = -1;
+
 #define DATA_BLOCK_SIZE     (27648*4) /* WinNT Latency is 600 msec read pa_dsound.c */
 #define SAMPLE_RATE         (44100)
 
@@ -72,6 +74,8 @@ static void close_output(void);
 static int output_data(char *buf, int32 nbytes);
 static int acntl(int request, void *arg);
 
+static void print_device_list(void);
+
 static int framesPerBuffer=128;
 static int stereo=2;
 static int conv16_32 =0;
@@ -85,6 +89,7 @@ static int first=1;
 
 #if PORTAUDIO_V19
 PaHostApiTypeId HostApiTypeId;
+PaHostApiIndex HostApiIndex;
 const PaHostApiInfo  *HostApiInfo;
 PaDeviceIndex DeviceIndex;
 const PaDeviceInfo *DeviceInfo;
@@ -285,7 +290,7 @@ static int open_output(void)
        double rate;
        int n, nrates, include_enc, exclude_enc;
        PaSampleFormat SampleFormat, nativeSampleFormats;
-
+       
 #ifdef AU_PORTAUDIO_DLL
 #if PORTAUDIO_V19
   {
@@ -326,31 +331,42 @@ static int open_output(void)
                pa_active = 1;
        }
 
+       if (opt_pa_device_id == -2){
+               print_device_list();
+               goto error2;
+       }
 #ifdef PORTAUDIO_V19
 #ifdef AU_PORTAUDIO_DLL
-       {
-               PaHostApiIndex i, ApiCount;
-               i = 0;
-               ApiCount = Pa_GetHostApiCount();
-               do{
-                       HostApiInfo=Pa_GetHostApiInfo(i);
-                       if( HostApiInfo->type == HostApiTypeId ) break;
-               i++;
-               }while ( i < ApiCount );
-               if ( i == ApiCount ) goto error;
-    }
+       PaHostApiIndex i, ApiCount;
+       i = 0;
+       ApiCount = Pa_GetHostApiCount();
+       do{
+               HostApiInfo=Pa_GetHostApiInfo(i);
+               if( HostApiInfo->type == HostApiTypeId ) break;
+               i++;
+       }while ( i < ApiCount );
+       if ( i == ApiCount ) goto error;
+       
        DeviceIndex = HostApiInfo->defaultOutputDevice;
        if(DeviceIndex==paNoDevice) goto error;
-       DeviceInfo = Pa_GetDeviceInfo( DeviceIndex);
-       if(DeviceInfo==NULL) goto error;
-
 #else
        DeviceIndex = Pa_GetDefaultOutputDevice();
        if(DeviceIndex==paNoDevice) goto error;
+#endif
        DeviceInfo = Pa_GetDeviceInfo( DeviceIndex);
        if(DeviceInfo==NULL) goto error;
-#endif
-       
+
+       if(opt_pa_device_id != -1){
+               const PaDeviceInfo *id_DeviceInfo;
+       id_DeviceInfo=Pa_GetDeviceInfo((PaDeviceIndex)opt_pa_device_id);
+               if(id_DeviceInfo==NULL) goto error;
+               if( DeviceInfo->hostApi == id_DeviceInfo->hostApi){
+                       DeviceIndex=(PaDeviceIndex)opt_pa_device_id;
+                       DeviceInfo = id_DeviceInfo;
+               }
+    }
+
+
        if (dpm.encoding & PE_24BIT) {
                SampleFormat = paInt24;
        }else if (dpm.encoding & PE_16BIT) {
@@ -414,8 +430,12 @@ static int open_output(void)
        return 0;
        
 #else
-       DeviceID = Pa_GetDefaultOutputDeviceID();
-       if(DeviceID==paNoDevice) goto error2;
+       if(opt_pa_device_id != -1){
+               DeviceID = Pa_GetDefaultOutputDeviceID();
+           if(DeviceID==paNoDevice) goto error2;
+       }else{
+               DeviceID = opt_pa_device_id;
+       }
        DeviceInfo = Pa_GetDeviceInfo( DeviceID);       
        if(DeviceInfo==NULL) goto error2;
        nativeSampleFormats = DeviceInfo->nativeSampleFormats;
@@ -646,3 +666,29 @@ error:
        ctl->cmsg(  CMSG_ERROR, VERB_NORMAL, "PortAudio error in acntl : %s\n", Pa_GetErrorText( err ) );
        return -1;
 }
+
+static void print_device_list(void){
+       PaDeviceIndex maxDeviceIndex, i;
+       PaHostApiIndex HostApiIndex;
+       const PaDeviceInfo* DeviceInfo;
+
+#if PORTAUDIO_V19
+       HostApiIndex=Pa_HostApiTypeIdToHostApiIndex(HostApiTypeId);
+#endif
+       
+       maxDeviceIndex=Pa_GetDeviceCount();
+       
+       for( i = 0; i < maxDeviceIndex; i++){
+               DeviceInfo=Pa_GetDeviceInfo(i);
+#if PORTAUDIO_V19
+               if( DeviceInfo->hostApi == HostApiIndex){
+#endif
+                       if( DeviceInfo->maxOutputChannels > 0){
+                               ctl->cmsg(  CMSG_ERROR, VERB_NORMAL, "%2d %s",i,DeviceInfo->name);
+                       }
+#if PORTAUDIO_V19
+               }
+#endif
+       }
+}
+
index c063226..70f0336 100644 (file)
@@ -178,6 +178,7 @@ enum {
        TIM_OPT_OUTPUT_BITWIDTH,
        TIM_OPT_OUTPUT_FORMAT,
        TIM_OPT_OUTPUT_SWAB,
+       TIM_OPT_OUTPUT_DEVICE,
        TIM_OPT_FLAC_VERIFY,
        TIM_OPT_FLAC_PADDING,
        TIM_OPT_FLAC_COMPLEVEL,
@@ -320,6 +321,9 @@ static const struct option longopts[] = {
        { "output-alaw",            no_argument,       NULL, TIM_OPT_OUTPUT_FORMAT },
        { "no-output-swab",         no_argument,       NULL, TIM_OPT_OUTPUT_SWAB },
        { "output-swab",            optional_argument, NULL, TIM_OPT_OUTPUT_SWAB },
+#if defined(AU_PORTAUDIO) || defined(AU_WIN32)
+       { "output-device",          required_argument, NULL, TIM_OPT_OUTPUT_DEVICE },
+#endif
 #ifdef AU_FLAC
        { "flac-verify",            no_argument,       NULL, TIM_OPT_FLAC_VERIFY },
        { "flac-padding",           required_argument, NULL, TIM_OPT_FLAC_PADDING },
@@ -383,6 +387,12 @@ char *opt_aq_max_buff = NULL,
      *opt_aq_fill_buff = NULL;
 void timidity_init_aq_buff(void);
 int opt_control_ratio = 0; /* Save -C option */
+#ifdef AU_PORTAUDIO
+extern int opt_pa_device_id;
+#endif
+#ifdef AU_W32
+extern int opt_wmme_device_id;
+#endif
 
 int set_extension_modes(char *);
 int set_ctl(char *);
@@ -460,6 +470,9 @@ static inline int parse_opt_output_signed(const char *);
 static inline int parse_opt_output_bitwidth(const char *);
 static inline int parse_opt_output_format(const char *);
 static inline int parse_opt_output_swab(const char *);
+#if defined(AU_PORTAUDIO) || defined(AU_W32)
+static inline int parse_opt_output_device(const char *);
+#endif
 #ifdef AU_FLAC
 static inline int parse_opt_flac_verify(const char *);
 static inline int parse_opt_flac_padding(const char *);
@@ -2804,6 +2817,10 @@ MAIN_INTERFACE int set_tim_opt_long(int c, char *optarg, int index)
                return parse_opt_output_format(arg);
        case TIM_OPT_OUTPUT_SWAB:
                return parse_opt_output_swab(arg);
+#if defined(AU_PORTAUDIO) || defined(AU_WIN32)
+       case TIM_OPT_OUTPUT_DEVICE:
+               return parse_opt_output_device(arg);
+#endif
 #ifdef AU_FLAC
        case TIM_OPT_FLAC_VERIFY:
                return parse_opt_flac_verify(arg);
@@ -3940,6 +3957,11 @@ static int parse_opt_h(const char *arg)
 "  `A'          A-Law encoding" NLS
 "  `x'          byte-swapped output" NLS, fp);
        fputs(NLS, fp);
+#if defined(AU_PORTAUDIO) || defined(AU_WIN32)
+       fputs("Output device options (append to -O? option):" NLS
+"  `d(num)'     OutputDeviceID(if blank show available device list)" NLS, fp);
+       fputs(NLS, fp);
+#endif
        fputs("Alternative output format long options:" NLS
 "  --output-stereo" NLS
 "  --output-mono" NLS
@@ -3953,6 +3975,12 @@ static int parse_opt_h(const char *arg)
 "  --output-alaw" NLS
 "  --[no-]output-swab" NLS, fp);
        fputs(NLS, fp);
+#if defined(AU_PORTAUDIO) || defined(AU_WIN32)
+       fputs("Output device long options:" NLS
+"  --output-device=n  (if n=-1 show available device list)" NLS, fp);
+       fputs(NLS, fp);
+#endif
+
        fputs("Available WRD interfaces (-W, --wrd option):" NLS, fp);
        for (wlpp = wrdt_list; (wlp = *wlpp) != NULL; wlpp++)
                fprintf(fp, "  -W%c          %s" NLS, wlp->id, wlp->name);
@@ -4330,6 +4358,36 @@ static inline int parse_opt_O(const char *arg)
                        pmp->encoding ^= PE_BYTESWAP;   /* toggle */
                        pmp->encoding &= ~(PE_ULAW | PE_ALAW);
                        break;
+#if defined(AU_PORTAUDIO) || defined(AU_W32)
+               case 'd':
+#ifdef AU_PORTAUDIO
+                       if (play_mode->id_character == 'p' || play_mode->id_character == 'P'||play_mode->id_character == 'o'){
+                               int ret;
+                               ret = sscanf(arg+1,"%d",&opt_pa_device_id);
+                               if( (ret != 0) && (ret != EOF) ){
+                                       while( *(arg+1) >= '0' && *(arg + 1) <= '9') { arg++; }
+                               }else{
+                                       opt_pa_device_id=-2;
+                                       play_mode->open_output();
+                                       return 1;
+                               }
+                       }
+#endif
+#ifdef AU_W32
+                       if (play_mode->id_character == 'd'){
+                               int ret;
+                               ret = sscanf(arg+1,"%d",&opt_wmme_device_id);
+                               if( (ret != 0) && (ret != EOF) ){
+                                       while( *(arg+1) >= '0' && *(arg + 1) <= '9') { arg++; }
+                               }else{                                  
+                                       opt_wmme_device_id=-2;
+                                       play_mode->open_output();
+                                       return 1;
+                               }
+                       }
+#endif
+                       break;
+#endif
                default:
                        ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
                                        "Unknown format modifier `%c'", *arg);
@@ -4415,6 +4473,37 @@ static inline int parse_opt_output_swab(const char *arg)
        return 0;
 }
 
+#if defined(AU_PORTAUDIO) || defined(AU_W32)
+static inline int parse_opt_output_device(const char *arg)
+{
+       if (arg == NULL) return 1;
+#ifdef AU_PORTAUDIO
+       if ( (play_mode->id_character == 'p') || (play_mode->id_character == 'P') || (play_mode->id_character == 'o') ){
+               int ret;
+               ret = sscanf(arg,"%d",&opt_pa_device_id);
+               if( (ret == 0) || (ret == EOF) ) return 1;              
+               if( opt_pa_device_id  ==  -1){
+                       opt_pa_device_id=-2;
+                       play_mode->open_output();
+                       return 1;
+               }
+       }
+#endif
+#ifdef AU_W32
+       if (play_mode->id_character == 'd'){
+               int ret;
+               ret = sscanf(arg,"%d",&opt_wmme_device_id);
+               if( (ret == 0) || (ret == EOF) ) return 1;              
+               if( opt_wmme_device_id  ==  -1){
+                       opt_wmme_device_id=-2;
+                       play_mode->open_output();
+                       return 1;
+               }
+       }
+#endif
+       return 0;
+}
+#endif
 #ifdef AU_FLAC
 extern void flac_set_option_verify(int);
 extern void flac_set_option_padding(int);
index 704c478..57c93a2 100644 (file)
@@ -43,6 +43,8 @@ extern void *safe_malloc(size_t count);
 
 extern CRITICAL_SECTION critSect;
 
+int opt_wmme_device_id = -1;
+
 /*****************************************************************************************************************************/
 
 #if defined(__CYGWIN32__) || defined(__MINGW32__)
@@ -143,6 +145,8 @@ static void close_output    (void);
 static int  output_data     (char * Data, int32 Size);
 static int  acntl           (int request, void * arg);
 
+static void print_device_list(void);
+
 #if defined ( IA_W32GUI ) || defined ( IA_W32G_SYN )
 //#if defined ( IA_W32GUI )
 volatile int data_block_bits = DEFAULT_AUDIO_BUFFER_BITS;
@@ -219,6 +223,11 @@ static int open_output(void)
     MMRESULT        Result;
     UINT            DeviceID;
 
+       if (opt_wmme_device_id == -2){
+               print_device_list();
+               return -1;
+       }
+
     if (dpm.extra_param[0] < 8)
     {
         ctl->cmsg(CMSG_WARNING, VERB_NORMAL, "Too small -B option: %d", dpm.extra_param[0]);
@@ -282,12 +291,19 @@ static int open_output(void)
 
     { CHAR  b[256]; wsprintf(b, "Opening device...\n"); OutputDebugString(b); }
 
-    hDevice = 0;
+               hDevice = 0;
+
+       UINT uDeviceID;
+       if (opt_wmme_device_id == -1){
+               uDeviceID = WAVE_MAPPER;
+    }else{
+       uDeviceID= (UINT)opt_wmme_device_id;
+       }
 
     if (AllowSynchronousWaveforms)
-        Result = waveOutOpen(&hDevice, WAVE_MAPPER, (LPWAVEFORMATEX) &wf, (DWORD) OnPlaybackEvent, 0, CALLBACK_FUNCTION | WAVE_ALLOWSYNC);
+        Result = waveOutOpen(&hDevice, uDeviceID, (LPWAVEFORMATEX) &wf, (DWORD) OnPlaybackEvent, 0, CALLBACK_FUNCTION | WAVE_ALLOWSYNC);
     else
-        Result = waveOutOpen(&hDevice, WAVE_MAPPER, (LPWAVEFORMATEX) &wf, (DWORD) OnPlaybackEvent, 0, CALLBACK_FUNCTION);
+        Result = waveOutOpen(&hDevice, uDeviceID, (LPWAVEFORMATEX) &wf, (DWORD) OnPlaybackEvent, 0, CALLBACK_FUNCTION);
 
     if (Result)
     {
@@ -762,3 +778,29 @@ static void WaitForBuffer(int WaitForAllBuffers)
         { CHAR  b[256]; wsprintf(b, "%2d: Wait finished.\n", NumBuffersInUse); OutputDebugString(b); }
     }
 }
+
+/*****************************************************************************************************************************/
+
+#define DEVLIST_MAX 20
+static void print_device_list(void){
+       UINT num;
+       int i, list_num;
+       WAVEOUTCAPS woc;
+       typedef struct tag_DEVICELIST{
+               int  deviceID;
+               char name[256];
+       } DEVICELIST;
+       DEVICELIST device[DEVLIST_MAX];
+       num = waveOutGetNumDevs();
+       list_num=0;
+       for(i = 0 ; i < num  && i < DEVLIST_MAX ; i++){
+               if (MMSYSERR_NOERROR == waveOutGetDevCaps((UINT)i, &woc, sizeof(woc)) ){
+                       device[list_num].deviceID=i;
+                       strcpy(device[list_num].name, woc.szPname);
+                       list_num++;
+               }
+       }
+       for(i=0;i<list_num;i++){
+               ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%2d %s", device[i].deviceID, device[i].name);
+       }
+}