Diff for /np2/x11/soundmng.c between versions 1.5 and 1.11

version 1.5, 2004/05/22 16:35:08 version 1.11, 2008/03/18 15:40:20
Line 1 Line 1
   /*      $Id$    */
   
 /*  /*
  * Copyright (c) 2001-2003 NONAKA Kimihiro   * Copyright (c) 2001-2003 NONAKA Kimihiro
  * All rights reserved.   * All rights reserved.
Line 10 Line 12
  * 2. Redistributions in binary form must reproduce the above copyright   * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the   *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.   *    documentation and/or other materials provided with the distribution.
  * 3. The name of the author may not be used to endorse or promote products  
  *    derived from this software without specific prior written permission.  
  *   *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR   * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES   * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
Line 33  BYTE Line 33  BYTE
 snddrv_drv2num(const char* cfgstr)  snddrv_drv2num(const char* cfgstr)
 {  {
   
         if (strcasecmp(cfgstr, "NetBSD") == 0)          if (strcasecmp(cfgstr, "SDL") == 0)
                 return SNDDRV_NETBSD;  
         else if (strcasecmp(cfgstr, "OSS") == 0)  
                 return SNDDRV_OSS;  
         else if (strcasecmp(cfgstr, "ESD") == 0)  
                 return SNDDRV_ESD;  
         else if (strcasecmp(cfgstr, "SDL") == 0)  
                 return SNDDRV_SDL;                  return SNDDRV_SDL;
         return SNDDRV_NODRV;          return SNDDRV_NODRV;
 }  }
Line 49  snddrv_num2drv(BYTE num) Line 43  snddrv_num2drv(BYTE num)
 {  {
   
         switch (num) {          switch (num) {
         case SNDDRV_NETBSD:  
                 return "NetBSD";  
         case SNDDRV_OSS:  
                 return "OSS";  
         case SNDDRV_ESD:  
                 return "ESD";  
         case SNDDRV_SDL:          case SNDDRV_SDL:
                 return "SDL";                  return "SDL";
         }          }
Line 69  snddrv_num2drv(BYTE num) Line 57  snddrv_num2drv(BYTE num)
 #include "dosio.h"  #include "dosio.h"
 #include "parts.h"  #include "parts.h"
   
   #include "sysmng.h"
 #include "sound.h"  #include "sound.h"
   
 #if defined(VERMOUTH_LIB)  #if defined(VERMOUTH_LIB)
 #include "vermouth.h"  #include "vermouth.h"
 #endif  
   
 #include "sysmng.h"  
   
 #if defined(VERMOUTH_LIB)  
 MIDIMOD vermouth_module = NULL;  MIDIMOD vermouth_module = NULL;
 #endif  #endif
   
Line 141  calc_fragment(UINT size) Line 127  calc_fragment(UINT size)
         return f;          return f;
 }  }
   
 void  static void
 snddrv_setup(void)  snddrv_setup(void)
 {  {
   
         if (np2oscfg.snddrv < SNDDRV_DRVMAX) {          if (np2oscfg.snddrv < SNDDRV_DRVMAX) {
                 switch (np2oscfg.snddrv) {                  switch (np2oscfg.snddrv) {
 #if defined(USE_NETBSDAUDIO)  
                 case SNDDRV_NETBSD:  
                         netbsdaudio_setup();  
                         return;  
 #endif  
 #if defined(USE_OSSAUDIO)  
                 case SNDDRV_OSS:  
                         ossaudio_setup();  
                         return;  
 #endif  
 #if defined(USE_ESDAUDIO)  
                 case SNDDRV_ESD:  
                         esdaudio_setup();  
                         return;  
 #endif  
 #if defined(USE_SDLAUDIO) || defined(USE_SDLMIXER)  #if defined(USE_SDLAUDIO) || defined(USE_SDLMIXER)
                 case SNDDRV_SDL:                  case SNDDRV_SDL:
 #if defined(USE_SDLMIXER)  #if defined(USE_SDLMIXER)
Line 187  snddrv_setup(void) Line 158  snddrv_setup(void)
                         return;                          return;
                 } else                  } else
 #endif  #endif
 #if defined(USE_ESDAUDIO)  
                 if (esdaudio_setup() == SUCCESS) {  
                         np2oscfg.snddrv = SNDDRV_ESD;  
                         sysmng_update(SYS_UPDATEOSCFG);  
                         return;  
                 } else  
 #endif  
 #if defined(USE_OSSAUDIO)  
                 if (ossaudio_setup() == SUCCESS) {  
                         np2oscfg.snddrv = SNDDRV_OSS;  
                         sysmng_update(SYS_UPDATEOSCFG);  
                         return;  
                 } else  
 #endif  
 #if defined(USE_NETBSDAUDIO)  
                 if (netbsdaudio_setup() == SUCCESS) {  
                         np2oscfg.snddrv = SNDDRV_NETBSD;  
                         sysmng_update(SYS_UPDATEOSCFG);  
                         return;  
                 } else  
 #endif  
                 {                  {
                         /* Nothing to do */                          /* Nothing to do */
                         /* fall thourgh "no match" */                          /* fall thourgh "no match" */
Line 349  void Line 299  void
 soundmng_setreverse(BOOL reverse)  soundmng_setreverse(BOOL reverse)
 {  {
   
 #if defined(GCC_CPU_ARCH_IA32)  #if defined(GCC_CPU_ARCH_AMD64)
           if (!reverse) {
                   if (mmxflag & (MMXFLAG_NOTSUPPORT|MMXFLAG_DISABLE)) {
                           fnmix = satuation_s16;
                   } else {
                           fnmix = saturation_s16mmx;
                   }
           } else {
                   fnmix = satuation_s16x;
           }
   #elif defined(GCC_CPU_ARCH_IA32)
         if (!reverse) {          if (!reverse) {
                 if (mmxflag & (MMXFLAG_NOTSUPPORT|MMXFLAG_DISABLE)) {                  if (mmxflag & (MMXFLAG_NOTSUPPORT|MMXFLAG_DISABLE)) {
                         fnmix = _saturation_s16;                          fnmix = _saturation_s16;
Line 586  nosound_setup(void) Line 546  nosound_setup(void)
         return SUCCESS;          return SUCCESS;
 }  }
   
 #if defined(USE_NETBSDAUDIO) || defined(USE_OSSAUDIO) || defined(USE_ESDAUDIO)  #if defined(GCC_CPU_ARCH_AMD64)
 /*  void PARTSCALL
  * common driver  _saturation_s16(SINT16 *dst, const SINT32 *src, UINT size)
  */  
 static pthread_t ptid;  
 static BOOL is_proc;  
   
 static void *  
 buffer_play(void *arg)  
 {  {
         char *buf;          asm volatile (
         size_t len = opna_frame;                  "movq   %0, %%rcx;"
         size_t s;                  "movq   %1, %%rdx;"
         ssize_t r;                  "movl   %2, %%ebx;"
         int nextbuf;                  "shrl   $1, %%ebx;"
                   "je     .ss16_ed;"
         UNUSED(arg);          ".ss16_lp:"
                   "movl   (%%rdx), %%eax;"
         is_proc = TRUE;                  "cmpl   $0x000008000, %%eax;"
         while (is_proc) {                  "jl     .ss16_min;"
                 nextbuf = sound_nextbuf;                  "movw   $0x7fff, %%ax;"
                 if (sound_event)                  "jmp    .ss16_set;"
                         memset(sound_event, 0, len);          ".ss16_min:"
                 sound_nextbuf = (sound_nextbuf + 1) % NSOUNDBUFFER;                  "cmpl   $0x0ffff8000, %%eax;"
                 sound_event = sound_buffer[sound_nextbuf];                  "jg     .ss16_set;"
                   "movw   $0x8001, %%ax;"
                 buf = sound_buffer[nextbuf];          ".ss16_set:"
                 s = 0;                  "leal   4(%%rdx), %%edx;"
                 for (;;) {                  "movw   %%ax, (%%rcx);"
                         r = write(audio_fd, buf + s, len - s);                  "decl   %%ebx;"
                         if (r >= 0) {                  "leal   2(%%rcx), %%ecx;"
                                 s += r;                  "jne    .ss16_lp;"
                                 if (len <= s)          ".ss16_ed:"
                                         break;                  : /* output */
                         }                  : "m" (dst), "m" (src), "m" (size)
                 }                  : "ebx");
         }  
         is_proc = FALSE;  
   
         return NULL;  
 }  }
   
 void  void PARTSCALL
 snddrv_play(void)  _saturation_s16x(SINT16 *dst, const SINT32 *src, UINT size)
 {  {
   
         if (pthread_create(&ptid, NULL, buffer_play, NULL) != 0) {          asm volatile (
                 fprintf(stderr, "audio_play: can't create thread.\n");                  "movq   %0, %%rcx;"
         }                  "movq   %1, %%rdx;"
                   "movl   %2, %%ebx;"
                   "shrl   $2, %%ebx;"
                   "je     .ss16x_ed;"
           ".ss16x_lp:"
                   "movl   (%%rdx), %%eax;"
                   "cmpl   $0x000008000, %%eax;"
                   "jl     .ss16xl_min;"
                   "movw   $0x7fff, %%ax;"
                   "jmp    .ss16xl_set;"
           ".ss16xl_min:"
                   "cmpl   $0x0ffff8000, %%eax;"
                   "jg     .ss16xl_set;"
                   "movw   $0x8001, %%ax;"
           ".ss16xl_set:"
                   "movw   %%ax, 2(%%rcx);"
                   "movl   4(%%rdx), %%eax;"
                   "cmpl   $0x000008000, %%eax;"
                   "jl     .ss16xr_min;"
                   "movw   $0x7fff, %%ax;"
                   "jmp    .ss16xr_set;"
           ".ss16xr_min:"
                   "cmpl   $0x0ffff8000, %%eax;"
                   "jg     .ss16xr_set;"
                   "mov    $0x8001, %%ax;"
           ".ss16xr_set:"
                   "movw   %%ax, (%%rcx);"
                   "leal   8(%%rdx), %%edx;"
                   "decl   %%ebx;"
                   "leal   4(%%rcx), %%ecx;"
                   "jne    .ss16x_lp;"
           ".ss16x_ed:"
                   : /* output */
                   : "m" (dst), "m" (src), "m" (size)
                   : "ebx");
 }  }
   
 void  void PARTSCALL
 snddrv_stop(void)  saturation_s16mmx(SINT16 *dst, const SINT32 *src, UINT size)
 {  {
   
         is_proc = FALSE;          asm volatile (
                   "movq   %0, %%rcx;"
                   "movq   %1, %%rdx;"
                   "movl   %2, %%eax;"
                   "shrl   $3, %%eax;"
                   "je     .ss16m_ed;"
                   "pxor   %%mm0, %%mm0;"
           ".ss16m_lp:"
                   "movq   (%%rdx), %%mm1;"
                   "movq   8(%%rdx), %%mm2;"
                   "packssdw %%mm2, %%mm1;"
                   "leaq   16(%%rdx), %%rdx;"
                   "movq   %%mm1, (%%rcx);"
                   "leaq   8(%%rcx), %%rcx;"
                   "dec    %%eax;"
                   "jne    .ss16m_lp;"
                   "emms;"
           ".ss16m_ed:"
                   : /* output */
                   : "m" (dst), "m" (src), "m" (size));
 }  }
   #elif defined(GCC_CPU_ARCH_IA32)
 #endif  /* USE_NETBSDAUDIO || USE_OSSAUDIO || USE_ESDAUDIO */  
   
 #if defined(GCC_CPU_ARCH_IA32)  
 void PARTSCALL  void PARTSCALL
 _saturation_s16(SINT16 *dst, const SINT32 *src, UINT size)  _saturation_s16(SINT16 *dst, const SINT32 *src, UINT size)
 {  {
Line 746  saturation_s16mmx(SINT16 *dst, const SIN Line 746  saturation_s16mmx(SINT16 *dst, const SIN
                 : /* output */                  : /* output */
                 : "m" (dst), "m" (src), "m" (size));                  : "m" (dst), "m" (src), "m" (size));
 }  }
 #endif  /* __GNUC__ && GCC_CPU_ARCH_IA32 */  #endif  /* GCC_CPU_ARCH_AMD64 */
   
   #if defined(USE_SDLAUDIO) || defined(USE_SDLMIXER)
   
   #include <SDL.h>
   
   static void sdlaudio_callback(void *, unsigned char *, int);
   
   #if defined(USE_SDLAUDIO)
   
   static BOOL
   sdlaudio_init(UINT rate, UINT samples)
   {
           static SDL_AudioSpec fmt;
           int rv;
   
           fmt.freq = rate;
           fmt.format = AUDIO_S16SYS;
           fmt.channels = 2;
           fmt.samples = samples;
           fmt.callback = sdlaudio_callback;
           fmt.userdata = (void *)(samples * 2 * sizeof(SINT16));
   
           rv = SDL_Init(SDL_INIT_AUDIO);
           if (rv < 0) {
                   fprintf(stderr, "sdlaudio_init: SDL_Init\n");
                   return FAILURE;
           }
   
           audio_fd = SDL_OpenAudio(&fmt, NULL);
           if (audio_fd < 0) {
                   fprintf(stderr, "sdlaudio_init: SDL_OpenAudio\n");
                   SDL_Quit();
                   return FAILURE;
           }
   
           return SUCCESS;
   }
   
   static BOOL
   sdlaudio_term(void)
   {
   
           SDL_CloseAudio();
           SDL_Quit();
   
           return SUCCESS;
   }
   
   static void
   sdlaudio_play(void)
   {
   
           SDL_PauseAudio(0);
   }
   
   static void
   sdlaudio_stop(void)
   {
   
           SDL_PauseAudio(1);
   }
   
   BOOL
   sdlaudio_setup(void)
   {
   
           snddrv.drvinit = sdlaudio_init;
           snddrv.drvterm = sdlaudio_term;
           snddrv.sndplay = sdlaudio_play;
           snddrv.sndstop = sdlaudio_stop;
           snddrv.pcmload = nosound_pcmload;
           snddrv.pcmdestroy = nosound_pcmdestroy;
           snddrv.pcmplay = nosound_pcmplay;
           snddrv.pcmstop = nosound_pcmstop;
           snddrv.pcmvolume = nosound_pcmvolume;
   
           return SUCCESS;
   }
   
   #endif  /* USE_SDLAUDIO */
   
   #if defined(USE_SDLMIXER)
   
   #include <SDL_mixer.h>
   
   static BOOL
   sdlmixer_init(UINT rate, UINT samples)
   {
           int rv;
   
           rv = SDL_Init(SDL_INIT_AUDIO);
           if (rv < 0) {
                   fprintf(stderr, "SDL_Init(): %s\n", SDL_GetError());
                   goto failure;
           }
   
           rv = Mix_OpenAudio(rate, AUDIO_S16SYS, 2, samples);
           if (rv < 0) {
                   fprintf(stderr, "Mix_OpenAudio(): %s\n", Mix_GetError());
                   goto failure1;
           }
           SDL_PauseAudio(1);
   
           rv = Mix_AllocateChannels(SOUND_MAXPCM);
           if (rv < 0) {
                   fprintf(stderr, "Mix_AllocateChannels(): %s\n", Mix_GetError());
                   goto failure2;
           }
   
           Mix_HookMusic(sdlaudio_callback, (void*)(samples * 2 * sizeof(SINT16)));
   
           return SUCCESS;
   
   failure2:
           Mix_CloseAudio();
   failure1:
           SDL_Quit();
   failure:
           return FAILURE;
   }
   
   static BOOL
   sdlmixer_term(void)
   {
   
           Mix_CloseAudio();
           SDL_Quit();
   
           return SUCCESS;
   }
   
   static void
   sdlmixer_play(void)
   {
   
           SDL_PauseAudio(0);
   }
   
   static void
   sdlmixer_stop(void)
   {
   
           SDL_PauseAudio(1);
   }
   
   static void *
   sdlmixer_pcmload(UINT num, const char *path)
   {
           Mix_Chunk *chunk;
   
           UNUSED(num);
   
           chunk = Mix_LoadWAV(path);
           return (void *)chunk;
   }
   
   static void
   sdlmixer_pcmdestroy(void *chanp, UINT num)
   {
           Mix_Chunk *chunk = (Mix_Chunk *)chanp;
   
           Mix_HaltChannel(num);
           Mix_FreeChunk(chunk);
   }
   
   static void
   sdlmixer_pcmplay(void *chanp, UINT num, BOOL loop)
   {
           Mix_Chunk *chunk = (Mix_Chunk *)chanp;
   
           Mix_PlayChannel(num, chunk, loop ? -1 : 1);
   }
   
   static void
   sdlmixer_pcmstop(void *chanp, UINT num)
   {
   
           UNUSED(chanp);
   
           Mix_HaltChannel(num);
   }
   
   static void
   sdlmixer_pcmvolume(void *chanp, UINT num, int volume)
   {
   
           UNUSED(chanp);
   
           Mix_Volume(num, (MIX_MAX_VOLUME * volume) / 100);
   }
   
   BOOL
   sdlmixer_setup(void)
   {
   
           snddrv.drvinit = sdlmixer_init;
           snddrv.drvterm = sdlmixer_term;
           snddrv.sndplay = sdlmixer_play;
           snddrv.sndstop = sdlmixer_stop;
           snddrv.pcmload = sdlmixer_pcmload;
           snddrv.pcmdestroy = sdlmixer_pcmdestroy;
           snddrv.pcmplay = sdlmixer_pcmplay;
           snddrv.pcmstop = sdlmixer_pcmstop;
           snddrv.pcmvolume = sdlmixer_pcmvolume;
   
           return SUCCESS;
   }
   
   #endif  /* USE_SDLMIXER */
   
   static void
   sdlaudio_callback(void *userdata, unsigned char *stream, int len)
   {
           UINT samples = (UINT)userdata;
           int nextbuf = sound_nextbuf;
   
           UNUSED(len);
   
           if (sound_event != NULL)
                   memset(sound_event, 0, samples);
           sound_nextbuf = (sound_nextbuf + 1) % NSOUNDBUFFER;
           sound_event = sound_buffer[sound_nextbuf];
   
           SDL_MixAudio(stream, (const void *)sound_buffer[nextbuf], samples,
               SDL_MIX_MAXVOLUME);
   }
   
   #endif  /* USE_SDLAUDIO || USE_SDLMIXER */
   
 #endif  /* !NOSOUND */  #endif  /* !NOSOUND */

Removed from v.1.5  
changed lines
  Added in v.1.11


RetroPC.NET-CVS <cvs@retropc.net>