Beispiel #1
0
static int pa_solaris_auto_format(int fd, int mode, pa_sample_spec *ss) {
    audio_info_t info;

    AUDIO_INITINFO(&info);

    if (mode != O_RDONLY) {
        info.play.sample_rate = ss->rate;
        info.play.channels = ss->channels;
        switch (ss->format) {
        case PA_SAMPLE_U8:
            info.play.precision = 8;
            info.play.encoding = AUDIO_ENCODING_LINEAR;
            break;
        case PA_SAMPLE_ALAW:
            info.play.precision = 8;
            info.play.encoding = AUDIO_ENCODING_ALAW;
            break;
        case PA_SAMPLE_ULAW:
            info.play.precision = 8;
            info.play.encoding = AUDIO_ENCODING_ULAW;
            break;
        case PA_SAMPLE_S16NE:
            info.play.precision = 16;
            info.play.encoding = AUDIO_ENCODING_LINEAR;
            break;
        default:
            return -1;
        }
    }

    if (mode != O_WRONLY) {
        info.record.sample_rate = ss->rate;
        info.record.channels = ss->channels;
        switch (ss->format) {
        case PA_SAMPLE_U8:
            info.record.precision = 8;
            info.record.encoding = AUDIO_ENCODING_LINEAR;
            break;
        case PA_SAMPLE_ALAW:
            info.record.precision = 8;
            info.record.encoding = AUDIO_ENCODING_ALAW;
            break;
        case PA_SAMPLE_ULAW:
            info.record.precision = 8;
            info.record.encoding = AUDIO_ENCODING_ULAW;
            break;
        case PA_SAMPLE_S16NE:
            info.record.precision = 16;
            info.record.encoding = AUDIO_ENCODING_LINEAR;
            break;
        default:
            return -1;
        }
    }

    if (ioctl(fd, AUDIO_SETINFO, &info) < 0) {
        if (errno == EINVAL)
            pa_log("AUDIO_SETINFO: Unsupported sample format.");
        else
            pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno));
        return -1;
    }

    return 0;
}
/*********************************************************************
 * Try to open the named device.
 * If it opens, try to set various rates and formats and fill in
 * the device info structure.
 */
PaError Pa_QueryDevice( const char *deviceName, internalPortAudioDevice *pad )
{
    int result = paHostError;
    int tempDevHandle;
    int numChannels, maxNumChannels;
    int numSampleRates;
    int sampleRate;
    int numRatesToTry;
    int ratesToTry[9] = {96000, 48000, 44100, 32000, 24000, 22050, 16000, 11025, 8000};
    int i;
    audio_info_t solaris_info;
    audio_device_t device_info;

    /* douglas:
     we have to do this querying in a slightly different order. apparently
     some sound cards will give you different info based on their settins.
     e.g. a card might give you stereo at 22kHz but only mono at 44kHz.
     the correct order for OSS is: format, channels, sample rate

    */
	/*
	 to check a device for it's capabilities, it's probably better to use the
	 equivalent "-ctl"-descriptor - MR
	*/
    char devname[strlen(deviceName) + 4];
    snprintf(devname,(strlen(deviceName) + 4),"%sctl",deviceName);

    if ((tempDevHandle = open(devname, O_WRONLY|O_NONBLOCK))  == -1 )
    {
        DBUG(("Pa_QueryDevice: could not open %s\n", deviceName ));
        return paHostError;
    }

    /*  Ask OSS what formats are supported by the hardware. */
    pad->pad_Info.nativeSampleFormats = 0;
    AUDIO_INITINFO(&solaris_info);

    /* SAM 12/31/01: Sparc native does mulaw, alaw and PCM.
       I think PCM is signed. */

    for (i = 8; i <= 32; i += 8) {
      solaris_info.play.precision = i;
      solaris_info.play.encoding = AUDIO_ENCODING_LINEAR;
      /* If there are no errors, add the format. */
      if (ioctl(tempDevHandle, AUDIO_SETINFO, &solaris_info) > -1) {
	switch (i) {
	case 8:
	  pad->pad_Info.nativeSampleFormats |= paInt8;
	  break;
	case 16:
	  pad->pad_Info.nativeSampleFormats |= paInt16;
	  break;
	case 24:
	  pad->pad_Info.nativeSampleFormats |= paInt24;
	  break;
	case 32:
	  pad->pad_Info.nativeSampleFormats |= paInt32;
	  break;
	}
      }
    }

    maxNumChannels = 0;
    for( numChannels = 1; numChannels <= 16; numChannels++ )
      {
	int temp = numChannels;
	DBUG(("Pa_QueryDevice: use SNDCTL_DSP_CHANNELS, numChannels = %d\n", numChannels ))
	  AUDIO_INITINFO(&solaris_info);
	solaris_info.play.channels = temp;
	if (ioctl(tempDevHandle, AUDIO_SETINFO, &solaris_info) < 0)
	  {
	    /* ioctl() failed so bail out if we already have stereo */
	    if( numChannels > 2 ) break;
	  }
	else
	  {
	    /* ioctl() worked but bail out if it does not support numChannels.
	     * We don't want to leave gaps in the numChannels supported.
	     */
	    if( (numChannels > 2) && (temp != numChannels) ) break;
	    DBUG(("Pa_QueryDevice: temp = %d\n", temp ))
	      if( temp > maxNumChannels ) maxNumChannels = temp; /* Save maximum. */
	  }
      }

    pad->pad_Info.maxOutputChannels = maxNumChannels;
    DBUG(("Pa_QueryDevice: maxNumChannels = %d\n", maxNumChannels))

    /* FIXME - for now, assume maxInputChannels = maxOutputChannels.
     *    Eventually do separate queries for O_WRONLY and O_RDONLY
    */
    pad->pad_Info.maxInputChannels = pad->pad_Info.maxOutputChannels;

    DBUG(("Pa_QueryDevice: maxInputChannels = %d\n",
          pad->pad_Info.maxInputChannels))


    /* Determine available sample rates by trying each one and seeing result.
     */
    numSampleRates = 0;

    AUDIO_INITINFO(&solaris_info);

    numRatesToTry = sizeof(ratesToTry)/sizeof(int);
    for (i = 0; i < numRatesToTry; i++)
    {
        sampleRate = ratesToTry[i];

	solaris_info.play.sample_rate = sampleRate; /* AS: We opened for Write, so set play */
        if (ioctl(tempDevHandle, AUDIO_SETINFO, &solaris_info) >= 0 ) /* PLB20010817 */
        {
            if (sampleRate == ratesToTry[i])
            {
                DBUG(("Pa_QueryDevice: got sample rate: %d\n", sampleRate))
                pad->pad_SampleRates[numSampleRates] = (float)ratesToTry[i];
                numSampleRates++;
            }
        }
    }

    DBUG(("Pa_QueryDevice: final numSampleRates = %d\n", numSampleRates))
    if (numSampleRates==0)   /* HP20010922 */
    {
        ERR_RPT(("Pa_QueryDevice: no supported sample rate (or SNDCTL_DSP_SPEED ioctl call failed).\n" ));
        goto error;
    }

    pad->pad_Info.numSampleRates = numSampleRates;
    pad->pad_Info.sampleRates = pad->pad_SampleRates;

    /* query for the device name instead of using the filesystem-device - MR */
	if (ioctl(tempDevHandle, AUDIO_GETDEV, &device_info) == -1) {
      pad->pad_Info.name = deviceName;
    } else {
      char *pt = (char *)PaHost_AllocateFastMemory(strlen(device_info.name));
      strcpy(pt, device_info.name);
      pad->pad_Info.name = pt;
    }

    result = paNoError;

error:
    /* We MUST close the handle here or we won't be able to reopen it later!!!  */
    close(tempDevHandle);

    return result;
}
Beispiel #3
0
static void input_sound(unsigned int sample_rate, unsigned int overlap,
                        const char *ifname)
{
    audio_info_t audioinfo;
    audio_info_t audioinfo2;
    audio_device_t audiodev;
    int fd;
    short buffer[8192];
    float fbuf[16384];
    unsigned int fbuf_cnt = 0;
    int i;
    short *sp;
    
    if ((fd = open(ifname ? ifname : "/dev/audio", O_RDONLY)) < 0) {
        perror("open");
        exit (10);
    }
    if (ioctl(fd, AUDIO_GETDEV, &audiodev) == -1) {
        perror("ioctl: AUDIO_GETDEV");
        exit (10);
    }
    AUDIO_INITINFO(&audioinfo);
    audioinfo.record.sample_rate = sample_rate;
    audioinfo.record.channels = 1;
    audioinfo.record.precision = 16;
    audioinfo.record.encoding = AUDIO_ENCODING_LINEAR;
    /*audioinfo.record.gain = 0x20;
      audioinfo.record.port = AUDIO_LINE_IN;
      audioinfo.monitor_gain = 0;*/
    if (ioctl(fd, AUDIO_SETINFO, &audioinfo) == -1) {
        perror("ioctl: AUDIO_SETINFO");
        exit (10);
    }
    if (ioctl(fd, I_FLUSH, FLUSHR) == -1) {
        perror("ioctl: I_FLUSH");
        exit (10);
    }
    if (ioctl(fd, AUDIO_GETINFO, &audioinfo2) == -1) {
        perror("ioctl: AUDIO_GETINFO");
        exit (10);
    }
    fprintf(stdout, "Audio device: name %s, ver %s, config %s, "
            "sampling rate %d\n", audiodev.name, audiodev.version,
            audiodev.config, audioinfo.record.sample_rate);
    for (;;) {
        i = read(fd, sp = buffer, sizeof(buffer));
        if (i < 0 && errno != EAGAIN) {
            perror("read");
            exit(4);
        }
        if (!i)
            break;
        if (i > 0) {
            if(integer_only)
        {
                fbuf_cnt = i/sizeof(buffer[0]);
        }
            else
            {
                for (; i >= sizeof(buffer[0]); i -= sizeof(buffer[0]), sp++)
                    fbuf[fbuf_cnt++] = (*sp) * (1.0/32768.0);
                if (i)
                    fprintf(stderr, "warning: noninteger number of samples read\n");
            }
            if (fbuf_cnt > overlap) {
                process_buffer(fbuf, buffer, fbuf_cnt-overlap);
                memmove(fbuf, fbuf+fbuf_cnt-overlap, overlap*sizeof(fbuf[0]));
                fbuf_cnt = overlap;
            }
        }
    }
    close(fd);
}
static int
SUNAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{
    const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT);
    SDL_AudioFormat format = 0;
    audio_info_t info;

    /* We don't care what the devname is...we'll try to open anything. */
    /*  ...but default to first name in the list... */
    if (devname == NULL) {
        devname = SDL_GetAudioDeviceName(0, iscapture);
        if (devname == NULL) {
            return SDL_SetError("No such audio device");
        }
    }

    /* Initialize all variables that we clean on shutdown */
    this->hidden = (struct SDL_PrivateAudioData *)
        SDL_malloc((sizeof *this->hidden));
    if (this->hidden == NULL) {
        return SDL_OutOfMemory();
    }
    SDL_memset(this->hidden, 0, (sizeof *this->hidden));

    /* Open the audio device */
    this->hidden->audio_fd = open(devname, flags, 0);
    if (this->hidden->audio_fd < 0) {
        return SDL_SetError("Couldn't open %s: %s", devname, strerror(errno));
    }

#ifdef AUDIO_SETINFO
    int enc;
#endif
    int desired_freq = this->spec.freq;

    /* Determine the audio parameters from the AudioSpec */
    switch (SDL_AUDIO_BITSIZE(this->spec.format)) {

    case 8:
        {                       /* Unsigned 8 bit audio data */
            this->spec.format = AUDIO_U8;
#ifdef AUDIO_SETINFO
            enc = AUDIO_ENCODING_LINEAR8;
#endif
        }
        break;

    case 16:
        {                       /* Signed 16 bit audio data */
            this->spec.format = AUDIO_S16SYS;
#ifdef AUDIO_SETINFO
            enc = AUDIO_ENCODING_LINEAR;
#endif
        }
        break;

    default:
        {
            /* !!! FIXME: fallback to conversion on unsupported types! */
            return SDL_SetError("Unsupported audio format");
        }
    }
    this->hidden->audio_fmt = this->spec.format;

    this->hidden->ulaw_only = 0;    /* modern Suns do support linear audio */
#ifdef AUDIO_SETINFO
    for (;;) {
        audio_info_t info;
        AUDIO_INITINFO(&info);  /* init all fields to "no change" */

        /* Try to set the requested settings */
        info.play.sample_rate = this->spec.freq;
        info.play.channels = this->spec.channels;
        info.play.precision = (enc == AUDIO_ENCODING_ULAW)
            ? 8 : this->spec.format & 0xff;
        info.play.encoding = enc;
        if (ioctl(this->hidden->audio_fd, AUDIO_SETINFO, &info) == 0) {

            /* Check to be sure we got what we wanted */
            if (ioctl(this->hidden->audio_fd, AUDIO_GETINFO, &info) < 0) {
                return SDL_SetError("Error getting audio parameters: %s",
                                    strerror(errno));
            }
            if (info.play.encoding == enc
                && info.play.precision == (this->spec.format & 0xff)
                && info.play.channels == this->spec.channels) {
                /* Yow! All seems to be well! */
                this->spec.freq = info.play.sample_rate;
                break;
            }
        }

        switch (enc) {
        case AUDIO_ENCODING_LINEAR8:
            /* unsigned 8bit apparently not supported here */
            enc = AUDIO_ENCODING_LINEAR;
            this->spec.format = AUDIO_S16SYS;
            break;              /* try again */

        case AUDIO_ENCODING_LINEAR:
            /* linear 16bit didn't work either, resort to µ-law */
            enc = AUDIO_ENCODING_ULAW;
            this->spec.channels = 1;
            this->spec.freq = 8000;
            this->spec.format = AUDIO_U8;
            this->hidden->ulaw_only = 1;
            break;

        default:
            /* oh well... */
            return SDL_SetError("Error setting audio parameters: %s",
                                strerror(errno));
        }
    }
#endif /* AUDIO_SETINFO */
    this->hidden->written = 0;

    /* We can actually convert on-the-fly to U-Law */
    if (this->hidden->ulaw_only) {
        this->spec.freq = desired_freq;
        this->hidden->fragsize = (this->spec.samples * 1000) /
            (this->spec.freq / 8);
        this->hidden->frequency = 8;
        this->hidden->ulaw_buf = (Uint8 *) SDL_malloc(this->hidden->fragsize);
        if (this->hidden->ulaw_buf == NULL) {
            return SDL_OutOfMemory();
        }
        this->spec.channels = 1;
    } else {
        this->hidden->fragsize = this->spec.samples;
        this->hidden->frequency = this->spec.freq / 1000;
    }
#ifdef DEBUG_AUDIO
    fprintf(stderr, "Audio device %s U-Law only\n",
            this->hidden->ulaw_only ? "is" : "is not");
    fprintf(stderr, "format=0x%x chan=%d freq=%d\n",
            this->spec.format, this->spec.channels, this->spec.freq);
#endif

    /* Update the fragment size as size in bytes */
    SDL_CalculateAudioSpec(&this->spec);

    /* Allocate mixing buffer */
    this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->spec.size);
    if (this->hidden->mixbuf == NULL) {
        return SDL_OutOfMemory();
    }
    SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);

    /* We're ready to rock and roll. :-) */
    return 0;
}
Beispiel #5
0
FILE *out_file_open(char *outFile, int rate, int *channels)
{
   FILE *fout=NULL;
   /*Open output file*/
   if (strlen(outFile)==0)
   {
#if defined HAVE_SYS_SOUNDCARD_H
      int audio_fd, format, stereo;
      audio_fd=open("/dev/dsp", O_WRONLY);
      if (audio_fd<0)
      {
         perror("Cannot open /dev/dsp");
         exit(1);         
      }

     format=AFMT_S16_NE;
//       format=AFMT_S16_LE;
      if (ioctl(audio_fd, SNDCTL_DSP_SETFMT, &format)==-1)
      {
         perror("SNDCTL_DSP_SETFMT");
         close(audio_fd);
         exit(1);
      }

      stereo=0;
      if (*channels==2)
         stereo=1;
      if (ioctl(audio_fd, SNDCTL_DSP_STEREO, &stereo)==-1)
      {
         perror("SNDCTL_DSP_STEREO");
         close(audio_fd);
         exit(1);
      }
      if (stereo!=0)
      {
         if (*channels==1)
            fprintf (stderr, "Cannot set mono mode, will decode in stereo\n");
         *channels=2;
      }

      if (ioctl(audio_fd, SNDCTL_DSP_SPEED, &rate)==-1)
      {
         perror("SNDCTL_DSP_SPEED");
         close(audio_fd);
         exit(1);
      }
      fout = fdopen(audio_fd, "w");
	  
	  printf ("/dev/dsp opened");
	  
#elif defined HAVE_SYS_AUDIOIO_H
      audio_info_t info;
      int audio_fd;
      
      audio_fd = open("/dev/audio", O_WRONLY);
      if (audio_fd<0)
      {
         perror("Cannot open /dev/audio");
         exit(1);
      }

      AUDIO_INITINFO(&info);
#ifdef AUMODE_PLAY    /* NetBSD/OpenBSD */
      info.mode = AUMODE_PLAY;
#endif
      info.play.encoding = AUDIO_ENCODING_SLINEAR;
      info.play.precision = 16;
      info.play.sample_rate = rate;
      info.play.channels = *channels;
      
      if (ioctl(audio_fd, AUDIO_SETINFO, &info) < 0)
      {
         perror ("AUDIO_SETINFO");
         exit(1);
      }
      fout = fdopen(audio_fd, "w");
#elif defined WIN32 || defined _WIN32
      {
         unsigned int speex_channels = *channels;
         if (Set_WIN_Params (INVALID_FILEDESC, rate, SAMPLE_SIZE, speex_channels))
         {
            fprintf (stderr, "Can't access %s\n", "WAVE OUT");
            exit(1);
         }
      }
#else
      fprintf (stderr, "No soundcard support\n");
      exit(1);
#endif
   } 
   
   return fout;
}
Beispiel #6
0
static int
sio_sun_setpar(struct sio_hdl *sh, struct sio_par *par)
{
#define NRETRIES 8
	struct sio_sun_hdl *hdl = (struct sio_sun_hdl *)sh;
	struct audio_info aui;
	unsigned int i, infr, ibpf, onfr, obpf;
	unsigned int bufsz, round;
	unsigned int rate, req_rate, prec, enc;

	/*
	 * try to set parameters until the device accepts
	 * a common encoding and rate for play and record
	 */
	rate = par->rate;
	prec = par->bits;
	sio_sun_enctoinfo(hdl, &enc, par);
	for (i = 0;; i++) {
		if (i == NRETRIES) {
			DPRINTF("sio_sun_setpar: couldn't set parameters\n");
			hdl->sio.eof = 1;
			return 0;
		}
		AUDIO_INITINFO(&aui);
		if (hdl->sio.mode & SIO_PLAY) {
			aui.play.sample_rate = rate;
			aui.play.precision = prec;
			aui.play.encoding = enc;
			aui.play.channels = par->pchan;
		}
		if (hdl->sio.mode & SIO_REC) {
			aui.record.sample_rate = rate;
			aui.record.precision = prec;
			aui.record.encoding = enc;
			aui.record.channels = par->rchan;
		}
		DPRINTFN(2, "sio_sun_setpar: %i: trying pars = %u/%u/%u\n",
		    i, rate, prec, enc);
		if (ioctl(hdl->fd, AUDIO_SETINFO, &aui) < 0 && errno != EINVAL) {
			DPERROR("sio_sun_setpar: setinfo(pars)");
			hdl->sio.eof = 1;
			return 0;
		}
		if (ioctl(hdl->fd, AUDIO_GETINFO, &aui) < 0) {
			DPERROR("sio_sun_setpar: getinfo(pars)");
			hdl->sio.eof = 1;
			return 0;
		}
		enc = (hdl->sio.mode & SIO_REC) ?
		    aui.record.encoding : aui.play.encoding;
		switch (enc) {
		case AUDIO_ENCODING_SLINEAR_LE:
		case AUDIO_ENCODING_SLINEAR_BE:
		case AUDIO_ENCODING_ULINEAR_LE:
		case AUDIO_ENCODING_ULINEAR_BE:
		case AUDIO_ENCODING_SLINEAR:
		case AUDIO_ENCODING_ULINEAR:
			break;
		default:
			DPRINTF("sio_sun_setpar: couldn't set linear encoding\n");
			hdl->sio.eof = 1;
			return 0;
		}
		if (hdl->sio.mode != (SIO_REC | SIO_PLAY))
			break;
		if (aui.play.sample_rate == aui.record.sample_rate &&
		    aui.play.precision == aui.record.precision &&
		    aui.play.encoding == aui.record.encoding)
			break;
		if (i < NRETRIES / 2) {
			rate = aui.play.sample_rate;
			prec = aui.play.precision;
			enc = aui.play.encoding;
		} else {
			rate = aui.record.sample_rate;
			prec = aui.record.precision;
			enc = aui.record.encoding;
		}
	}

	/*
	 * If the rate that the hardware is using is different than
	 * the requested rate, scale buffer sizes so they will be the
	 * same time duration as what was requested.  This just gets
	 * the rates to use for scaling, that actual scaling is done
	 * later.
	 */
	rate = (hdl->sio.mode & SIO_REC) ? aui.record.sample_rate :
	    aui.play.sample_rate;
	req_rate = rate;
	if (par->rate && par->rate != ~0U)
		req_rate = par->rate;

	/*
	 * if block size and buffer size are not both set then
	 * set the blocksize to half the buffer size
	 */
	bufsz = par->appbufsz;
	round = par->round;
	if (bufsz != ~0U) {
		bufsz = bufsz * rate / req_rate;
		if (round == ~0U)
			round = (bufsz + 1) / 2;
		else
			round = round * rate / req_rate;
	} else if (round != ~0U) {
		round = round * rate / req_rate;
		bufsz = round * 2;
	} else
		return 1;

	/*
	 * get the play/record frame size in bytes
	 */
	if (ioctl(hdl->fd, AUDIO_GETINFO, &aui) < 0) {
		DPERROR("sio_sun_setpar: GETINFO");
		hdl->sio.eof = 1;
		return 0;
	}
	ibpf = (hdl->sio.mode & SIO_REC) ?
	    aui.record.channels * aui.record.bps : 1;
	obpf = (hdl->sio.mode & SIO_PLAY) ?
	    aui.play.channels * aui.play.bps : 1;

	DPRINTFN(2, "sio_sun_setpar: bpf = (%u, %u)\n", ibpf, obpf);

	/*
	 * try to set parameters until the device accepts
	 * a common block size for play and record
	 */
	for (i = 0; i < NRETRIES; i++) {
		AUDIO_INITINFO(&aui);
		aui.hiwat = (bufsz + round - 1) / round;
		aui.lowat = aui.hiwat;
		if (hdl->sio.mode & SIO_REC)
			aui.record.block_size = round * ibpf;
		if (hdl->sio.mode & SIO_PLAY)
			aui.play.block_size = round * obpf;
		if (ioctl(hdl->fd, AUDIO_SETINFO, &aui) < 0) {
			DPERROR("sio_sun_setpar2: SETINFO");
			hdl->sio.eof = 1;
			return 0;
		}
		if (ioctl(hdl->fd, AUDIO_GETINFO, &aui) < 0) {
			DPERROR("sio_sun_setpar2: GETINFO");
			hdl->sio.eof = 1;
			return 0;
		}
		infr = aui.record.block_size / ibpf;
		onfr = aui.play.block_size / obpf;
		DPRINTFN(2, "sio_sun_setpar: %i: trying round = %u -> (%u, %u)\n",
		    i, round, infr, onfr);

		/*
		 * if half-duplex or both block sizes match, we're done
		 */
		if (hdl->sio.mode != (SIO_REC | SIO_PLAY) || infr == onfr) {
			DPRINTFN(2, "sio_sun_setpar: blocksize ok\n");
			return 1;
		}

		/*
		 * half of the retries, retry with the smaller value,
		 * then with the larger returned value
		 */
		if (i < NRETRIES / 2)
			round = infr < onfr ? infr : onfr;
		else
			round = infr < onfr ? onfr : infr;
	}
	DPRINTFN(2, "sio_sun_setpar: couldn't find a working blocksize\n");
	hdl->sio.eof = 1;
	return 0;
#undef NRETRIES
}
Beispiel #7
0
//PORTING: This function contains a ton of OS specific stuff. Hack and
//         slash at will.
Error SoundCardPMO::Init(OutputInfo * info)
{
   m_properlyInitialized = false;

   if (!info)
   {
      info = myInfo;
   }
   else
   {
      // got info, so this is the beginning...
      if ((audio_fd = open("/dev/audio", O_WRONLY, 0)) < 0)
      {
         if (errno == EBUSY)
         {
            ReportError("Audio device is busy. Please make sure that "
                        "another program is not using the device.");
            return (Error) pmoError_DeviceOpenFailed;
         }
         else
         {
            ReportError("Cannot open audio device. Please make sure that "
                        "the audio device is properly configured.");
            return (Error) pmoError_DeviceOpenFailed;
         }
      }

      m_iDataSize = info->max_buffer_size;
   }

   int       fd = audio_fd;
   struct audio_info ainfo;

   if (ioctl(audio_fd, AUDIO_GETINFO, &ainfo) < 0)
   {
      ReportError("Cannot get the flags on the audio device.");
      return (Error) pmoError_IOCTL_F_GETFL;
   }

   audio_fd = fd;

   channels = info->number_of_channels;

   for (unsigned int i = 0; i < info->number_of_channels; ++i)
      bufferp[i] = buffer + i;

   // configure the device:
   int       play_precision = 16;
//   int       play_stereo = channels - 1;
   int       play_sample_rate = info->samples_per_second;

   if (ioctl(audio_fd, I_FLUSH, FLUSHRW) == -1)
   {
      ReportError("Cannot reset the soundcard.");
      return (Error) pmoError_IOCTL_SNDCTL_DSP_RESET;
   }
   
   AUDIO_INITINFO(&ainfo);
   ainfo.play.precision = play_precision;
   ainfo.play.channels = channels;
   ainfo.play.sample_rate = play_sample_rate;
   ainfo.play.encoding = AUDIO_ENCODING_LINEAR;

   if (ioctl(audio_fd, AUDIO_SETINFO, &ainfo) == -1)
   {
      ReportError("Cannot set the soundcard's sampling speed.");
      return (Error) pmoError_IOCTL_SNDCTL_DSP_SPEED;
   }
   myInfo->bits_per_sample = info->bits_per_sample;
   myInfo->number_of_channels = info->number_of_channels;
   myInfo->samples_per_second = info->samples_per_second;
   myInfo->max_buffer_size = info->max_buffer_size;
   m_properlyInitialized = true;

   // PORTING: The GETOSPACE ioctl determines how much space the kernel's
   // output buffer has. Your OS may not have this.

   m_iTotalFragments = 2048; /* An arbitrary value of 2048. */
   m_iOutputBufferSize = play_precision * m_iTotalFragments;
   m_iBytesPerSample = info->number_of_channels * (info->bits_per_sample / 8);

   return kError_NoErr;
}
Beispiel #8
0
/*
 * Initialize the audio device.
 * This routine must set the following external variables:
 *      rplay_audio_sample_rate
 *      rplay_audio_precision
 *      rplay_audio_channels
 *      rplay_audio_format
 *      rplay_audio_port
 *
 * and may use the following optional parameters:
 *      optional_sample_rate
 *      optional_precision
 *      optional_channels
 *      optional_format
 *      optional_port
 *
 * optional_* variables with values of zero should be ignored.
 *
 * Return 0 on success and -1 on error.
 */
int
rplay_audio_init()
{
    audio_info_t a;
    audio_device_t d;

    if (rplay_audio_fd == -1)
    {
	rplay_audio_open();
	if (rplay_audio_fd == -1)
	{
	    report(REPORT_ERROR, "rplay_audio_init: cannot open %s\n",
		   rplay_audio_device);
	    return -1;
	}
    }

    if (ioctl(rplay_audio_fd, AUDIO_GETDEV, &d) < 0)
    {
	report(REPORT_ERROR, "rplay_audio_init: AUDIO_GETDEV: %s\n",
	       sys_err_str(errno));
	return -1;
    }

    if (strcmp(d.name, "SUNW,dbri") == 0)
    {
	report(REPORT_DEBUG, "%s device detected\n", d.name);
	rplay_audio_sample_rate = optional_sample_rate ? optional_sample_rate : 11025;
	rplay_audio_precision = optional_precision ? optional_precision : 16;
	rplay_audio_channels = optional_channels ? optional_channels : 1;
	rplay_audio_format = optional_format ? optional_format :
	    rplay_audio_precision == 16 ? RPLAY_FORMAT_LINEAR_16 : RPLAY_FORMAT_LINEAR_8;
	rplay_audio_port = optional_port ? optional_port : RPLAY_AUDIO_PORT_LINEOUT | RPLAY_AUDIO_PORT_SPEAKER;
	rplay_audio_table = dbri_table;
    }
    else if (strcmp(d.name, "SUNW,CS4231") == 0)
    {
	report(REPORT_DEBUG, "%s device detected\n", d.name);
	rplay_audio_sample_rate = optional_sample_rate ? optional_sample_rate : 11025;
	rplay_audio_precision = optional_precision ? optional_precision : 16;
	rplay_audio_channels = optional_channels ? optional_channels : 1;
	rplay_audio_format = optional_format ? optional_format :
	    rplay_audio_precision == 16 ? RPLAY_FORMAT_LINEAR_16 : RPLAY_FORMAT_LINEAR_8;
	rplay_audio_port = optional_port ? optional_port : RPLAY_AUDIO_PORT_LINEOUT | RPLAY_AUDIO_PORT_SPEAKER;
	rplay_audio_table = dbri_table;		/* use the dbri table */
    }
    else if (strcmp(d.name, "SUNW,am79c30") == 0)
    {
	report(REPORT_DEBUG, "%s device detected\n", d.name);
	rplay_audio_sample_rate = optional_sample_rate ? optional_sample_rate : 8000;
	rplay_audio_precision = optional_precision ? optional_precision : 8;
	rplay_audio_channels = optional_channels ? optional_channels : 1;
	rplay_audio_format = optional_format ? optional_format : RPLAY_FORMAT_ULAW;
	rplay_audio_port = optional_port ? optional_port : RPLAY_AUDIO_PORT_SPEAKER;
	rplay_audio_table = amd_table;
    }
    else if (strcmp(d.name, "SUNW,sb16") == 0)
    {
	report(REPORT_DEBUG, "%s device detected\n", d.name);
	rplay_audio_sample_rate = optional_sample_rate ? optional_sample_rate : 44100;
	rplay_audio_precision = optional_precision ? optional_precision : 16;
	rplay_audio_channels = optional_channels ? optional_channels : 2;
	rplay_audio_format = optional_format ? optional_format :
	    rplay_audio_precision == 16 ? RPLAY_FORMAT_LINEAR_16 : RPLAY_FORMAT_LINEAR_8;
	rplay_audio_port = optional_port ? optional_port : RPLAY_AUDIO_PORT_LINEOUT | RPLAY_AUDIO_PORT_SPEAKER;
	rplay_audio_table = dbri_table;		/* use the dbri table */
    }
    else
    {
	report(REPORT_ERROR, "`%s' unknown audio device detected\n", d.name);
	return -1;
    }

    /* Verify the precision and format. */
    switch (rplay_audio_precision)
    {
    case 8:
	if (rplay_audio_format != RPLAY_FORMAT_ULAW
	    && rplay_audio_format != RPLAY_FORMAT_LINEAR_8)
	{
	    report(REPORT_ERROR, "rplay_audio_init: can't use %d bits with format=%d\n",
		   rplay_audio_precision, rplay_audio_format);
	    return -1;
	}
	break;

    case 16:
	if (rplay_audio_format != RPLAY_FORMAT_LINEAR_16)
	{
	    report(REPORT_ERROR, "rplay_audio_init: can't use %d bits with format=%d\n",
		   rplay_audio_precision, rplay_audio_format);
	    return -1;
	}
	break;

    default:
	report(REPORT_ERROR, "rplay_audio_init: `%d' unsupported audio precision\n",
	       rplay_audio_precision);
	return -1;
    }

    AUDIO_INITINFO(&a);

    switch (rplay_audio_format)
    {
    case RPLAY_FORMAT_ULAW:
	a.play.encoding = AUDIO_ENCODING_ULAW;
	break;

    case RPLAY_FORMAT_LINEAR_8:
    case RPLAY_FORMAT_LINEAR_16:
	a.play.encoding = AUDIO_ENCODING_LINEAR;
	break;

    default:
	report(REPORT_ERROR, "rplay_audio_init: unsupported audio format `%d'\n",
	       rplay_audio_format);
	return -1;
    }

    /* Audio port. */
    if (rplay_audio_port == RPLAY_AUDIO_PORT_NONE)
    {
	a.play.port = ~0;	/* see AUDIO_INITINFO in /usr/include/sys/audioio.h. */
    }
    else
    {
	a.play.port = 0;
	if (BIT(rplay_audio_port, RPLAY_AUDIO_PORT_LINEOUT))
	{
#ifdef AUDIO_LINE_OUT
	    SET_BIT(a.play.port, AUDIO_LINE_OUT);
#else
	    CLR_BIT(rplay_audio_port, RPLAY_AUDIO_PORT_LINEOUT);
#endif
	}
	if (BIT(rplay_audio_port, RPLAY_AUDIO_PORT_HEADPHONE))
	{
#ifdef AUDIO_HEADPHONE
	    SET_BIT(a.play.port, AUDIO_HEADPHONE);
#else
	    CLR_BIT(rplay_audio_port, RPLAY_AUDIO_PORT_HEADPHONE);
#endif
	}
	if (BIT(rplay_audio_port, RPLAY_AUDIO_PORT_SPEAKER))
	{
#ifdef AUDIO_SPEAKER
	    SET_BIT(a.play.port, AUDIO_SPEAKER);
#endif
	    /* Assume speaker is okay. */
	}
    }

    a.play.sample_rate = rplay_audio_sample_rate;
    a.play.precision = rplay_audio_precision;
    a.play.channels = rplay_audio_channels;

    if (ioctl(rplay_audio_fd, AUDIO_SETINFO, &a) < 0)
    {
	report(REPORT_ERROR, "rplay_audio_init: AUDIO_SETINFO: %s\n", sys_err_str(errno));
	return -1;
    }

    return 0;
}
Beispiel #9
0
int
DSP_OpenAudio(_THIS, SDL_AudioSpec * spec)
{
    char audiodev[1024];
#ifdef AUDIO_SETINFO
    int enc;
#endif
    int desired_freq = spec->freq;

    /* Initialize our freeable variables, in case we fail */
    audio_fd = -1;
    mixbuf = NULL;
    ulaw_buf = NULL;

    /* Determine the audio parameters from the AudioSpec */
    switch (SDL_AUDIO_BITSIZE(spec->format)) {

    case 8:
        {                       /* Unsigned 8 bit audio data */
            spec->format = AUDIO_U8;
#ifdef AUDIO_SETINFO
            enc = AUDIO_ENCODING_LINEAR8;
#endif
        }
        break;

    case 16:
        {                       /* Signed 16 bit audio data */
            spec->format = AUDIO_S16SYS;
#ifdef AUDIO_SETINFO
            enc = AUDIO_ENCODING_LINEAR;
#endif
        }
        break;

    default:
        {
            /* !!! FIXME: fallback to conversion on unsupported types! */
            SDL_SetError("Unsupported audio format");
            return (-1);
        }
    }
    audio_fmt = spec->format;

    /* Open the audio device */
    audio_fd = SDL_OpenAudioPath(audiodev, sizeof(audiodev), OPEN_FLAGS, 1);
    if (audio_fd < 0) {
        SDL_SetError("Couldn't open %s: %s", audiodev, strerror(errno));
        return (-1);
    }

    ulaw_only = 0;              /* modern Suns do support linear audio */
#ifdef AUDIO_SETINFO
    for (;;) {
        audio_info_t info;
        AUDIO_INITINFO(&info);  /* init all fields to "no change" */

        /* Try to set the requested settings */
        info.play.sample_rate = spec->freq;
        info.play.channels = spec->channels;
        info.play.precision = (enc == AUDIO_ENCODING_ULAW)
            ? 8 : spec->format & 0xff;
        info.play.encoding = enc;
        if (ioctl(audio_fd, AUDIO_SETINFO, &info) == 0) {

            /* Check to be sure we got what we wanted */
            if (ioctl(audio_fd, AUDIO_GETINFO, &info) < 0) {
                SDL_SetError("Error getting audio parameters: %s",
                             strerror(errno));
                return -1;
            }
            if (info.play.encoding == enc
                && info.play.precision == (spec->format & 0xff)
                && info.play.channels == spec->channels) {
                /* Yow! All seems to be well! */
                spec->freq = info.play.sample_rate;
                break;
            }
        }

        switch (enc) {
        case AUDIO_ENCODING_LINEAR8:
            /* unsigned 8bit apparently not supported here */
            enc = AUDIO_ENCODING_LINEAR;
            spec->format = AUDIO_S16SYS;
            break;              /* try again */

        case AUDIO_ENCODING_LINEAR:
            /* linear 16bit didn't work either, resort to µ-law */
            enc = AUDIO_ENCODING_ULAW;
            spec->channels = 1;
            spec->freq = 8000;
            spec->format = AUDIO_U8;
            ulaw_only = 1;
            break;

        default:
            /* oh well... */
            SDL_SetError("Error setting audio parameters: %s",
                         strerror(errno));
            return -1;
        }
    }
#endif /* AUDIO_SETINFO */
    written = 0;

    /* We can actually convert on-the-fly to U-Law */
    if (ulaw_only) {
        spec->freq = desired_freq;
        fragsize = (spec->samples * 1000) / (spec->freq / 8);
        frequency = 8;
        ulaw_buf = (Uint8 *) SDL_malloc(fragsize);
        if (ulaw_buf == NULL) {
            SDL_OutOfMemory();
            return (-1);
        }
        spec->channels = 1;
    } else {
        fragsize = spec->samples;
        frequency = spec->freq / 1000;
    }
#ifdef DEBUG_AUDIO
    fprintf(stderr, "Audio device %s U-Law only\n",
            ulaw_only ? "is" : "is not");
    fprintf(stderr, "format=0x%x chan=%d freq=%d\n",
            spec->format, spec->channels, spec->freq);
#endif

    /* Update the fragment size as size in bytes */
    SDL_CalculateAudioSpec(spec);

    /* Allocate mixing buffer */
    mixbuf = (Uint8 *) SDL_AllocAudioMem(spec->size);
    if (mixbuf == NULL) {
        SDL_OutOfMemory();
        return (-1);
    }
    SDL_memset(mixbuf, spec->silence, spec->size);

    /* We're ready to rock and roll. :-) */
    return (0);
}
Beispiel #10
0
void
xf86OSRingBell(int loudness, int pitch, int duration)
{
    static short    samples[BELL_SAMPLES];
    static short    silence[BELL_SAMPLES]; /* "The Sound of Silence" */
    static int      lastFreq;
    int             cnt; 
    int             i;
    int             written;
    int             repeats;
    int             freq;
    audio_info_t    audioInfo;
    struct iovec    iov[IOV_MAX];
    int             iovcnt;
    double          ampl, cyclen, phase;
    int             audioFD;

    if ((loudness <= 0) || (pitch <= 0) || (duration <= 0)) {
        return;
    }

    lastFreq = 0;
    memset(silence, 0, sizeof(silence));

    audioFD = open(AUDIO_DEVICE, O_WRONLY | O_NONBLOCK);
    if (audioFD == -1) {
        xf86Msg(X_ERROR, "Bell: cannot open audio device \"%s\": %s\n",
                AUDIO_DEVICE, strerror(errno));
        return;
    }

    freq = pitch;
    freq = min(freq, (BELL_RATE / 2) - 1);
    freq = max(freq, 2 * BELL_HZ);

    /*
     * Ensure full waves per buffer
     */
    freq -= freq % BELL_HZ;

    if (freq != lastFreq) {
        lastFreq = freq;
        ampl =  16384.0;

        cyclen = (double) freq / (double) BELL_RATE;
        phase = 0.0;

        for (i = 0; i < BELL_SAMPLES; i++) {
            samples[i] = (short) (ampl * sin(2.0 * M_PI * phase));
            phase += cyclen;
            if (phase >= 1.0)
                phase -= 1.0;
        }
    }

    repeats = (duration + (BELL_MS / 2)) / BELL_MS;
    repeats = max(repeats, BELL_MIN);

    loudness = max(0, loudness);
    loudness = min(loudness, 100);

#ifdef DEBUG
    ErrorF("BELL : freq %d volume %d duration %d repeats %d\n",
           freq, loudness, duration, repeats);
#endif

    AUDIO_INITINFO(&audioInfo);
    audioInfo.play.encoding = AUDIO_ENCODING_LINEAR;
    audioInfo.play.sample_rate = BELL_RATE;
    audioInfo.play.channels = 2;
    audioInfo.play.precision = 16;
    audioInfo.play.gain = min(AUDIO_MAX_GAIN, AUDIO_MAX_GAIN * loudness / 100);

    if (ioctl(audioFD, AUDIO_SETINFO, &audioInfo) < 0){
        xf86Msg(X_ERROR,
                "Bell: AUDIO_SETINFO failed on audio device \"%s\": %s\n",
                AUDIO_DEVICE, strerror(errno));
        close(audioFD);
        return;
    }

    iovcnt = 0;

    for (cnt = 0; cnt <= repeats; cnt++) {
        if (cnt == repeats) {
            /* Insert a bit of silence so that multiple beeps are distinct and
             * not compressed into a single tone.
             */
            iov[iovcnt].iov_base = (char *) silence;
            iov[iovcnt++].iov_len = sizeof(silence);
        } else {
            iov[iovcnt].iov_base = (char *) samples;
            iov[iovcnt++].iov_len = sizeof(samples);
        }
        if ((iovcnt >= IOV_MAX) || (cnt == repeats)) {
            written = writev(audioFD, iov, iovcnt);

            if ((written < ((int)(sizeof(samples) * iovcnt)))) {
                /* audio buffer was full! */

                int naptime;

                if (written == -1) {
                    if (errno != EAGAIN) {
                        xf86Msg(X_ERROR,
                               "Bell: writev failed on audio device \"%s\": %s\n",
                                AUDIO_DEVICE, strerror(errno));
                        close(audioFD);
                        return;
                    }
                    i = iovcnt;
                } else {
                    i = ((sizeof(samples) * iovcnt) - written)
                        / sizeof(samples);
                }
                cnt -= i;

                /* sleep a little to allow audio buffer to drain */
                naptime = BELL_MS * i;
                poll(NULL, 0, naptime);

                i = ((sizeof(samples) * iovcnt) - written) % sizeof(samples);
                iovcnt = 0;
                if ((written != -1) && (i > 0)) {
                    iov[iovcnt].iov_base = ((char *) samples) + i;
                    iov[iovcnt++].iov_len = sizeof(samples) - i;
                }
            } else {
                iovcnt = 0;
            }
        }
    }

    close(audioFD);
    return;
}
Beispiel #11
0
static int init(struct options *options)
{
	char **parm = options->driver_parm;
	audio_info_t ainfo;
	int gain = 128;
	int bsize = 32 * 1024;

	parm_init(parm);
	chkparm1("gain", gain = strtoul(token, NULL, 0));
	chkparm1("buffer", bsize = strtoul(token, NULL, 0));
	parm_end();

	if ((audio_fd = open("/dev/sound", O_WRONLY)) == -1)
		return -1;

	/* try to open audioctldevice */
	if ((audioctl_fd = open("/dev/audioctl", O_RDWR)) < 0) {
		fprintf(stderr, "couldn't open audioctldevice\n");
		close(audio_fd);
		return -1;
	}

	/* empty buffers before change config */
	ioctl(audio_fd, AUDIO_DRAIN, 0);	/* drain everything out */
	ioctl(audio_fd, AUDIO_FLUSH);		/* flush audio */
	ioctl(audioctl_fd, AUDIO_FLUSH);	/* flush audioctl */

	/* get audio parameters. */
	if (ioctl(audioctl_fd, AUDIO_GETINFO, &ainfo) < 0) {
		fprintf(stderr, "AUDIO_GETINFO failed!\n");
		close(audio_fd);
		close(audioctl_fd);
		return -1;
	}

	close(audioctl_fd);

	if (gain < AUDIO_MIN_GAIN)
		gain = AUDIO_MIN_GAIN;
	if (gain > AUDIO_MAX_GAIN)
		gain = AUDIO_MAX_GAIN;

	AUDIO_INITINFO(&ainfo);

	ainfo.play.sample_rate = options->rate;
	ainfo.play.channels = options->format & XMP_FORMAT_MONO ? 1 : 2;

	if (options->format & XMP_FORMAT_8BIT) {
		ainfo.play.precision = 8;
		ainfo.play.precision = AUDIO_ENCODING_ULINEAR;
		options->format |= XMP_FORMAT_UNSIGNED;
	} else {
		ainfo.play.precision = 16;
		ainfo.play.precision = AUDIO_ENCODING_SLINEAR;
		options->format &= ~XMP_FORMAT_UNSIGNED;
	}

	ainfo.play.gain = gain;
	ainfo.play.buffer_size = bsize;

	if (ioctl(audio_fd, AUDIO_SETINFO, &ainfo) == -1) {
		close(audio_fd);
		return -1;
	}

	return 0;
}
FILE *out_file_open(char *outFile, int *wav_format, int rate, int mapping_family, int *channels)
{
   FILE *fout=NULL;
   /*Open output file*/
   if (strlen(outFile)==0)
   {
#if defined HAVE_SYS_SOUNDCARD_H
      int audio_fd, format, stereo;
      audio_fd=open("/dev/dsp", O_WRONLY);
      if (audio_fd<0)
      {
         perror("Cannot open /dev/dsp");
         quit(1);
      }

      format=AFMT_S16_NE;
      if (ioctl(audio_fd, SNDCTL_DSP_SETFMT, &format)==-1)
      {
         perror("SNDCTL_DSP_SETFMT");
         close(audio_fd);
         quit(1);
      }

      stereo=0;
      if (*channels==2)
         stereo=1;
      if (ioctl(audio_fd, SNDCTL_DSP_STEREO, &stereo)==-1)
      {
         perror("SNDCTL_DSP_STEREO");
         close(audio_fd);
         quit(1);
      }
      if (stereo!=0)
      {
         if (*channels==1)
            fprintf (stderr, "Cannot set mono mode, will decode in stereo\n");
         *channels=2;
      }

      if (ioctl(audio_fd, SNDCTL_DSP_SPEED, &rate)==-1)
      {
         perror("SNDCTL_DSP_SPEED");
         close(audio_fd);
         quit(1);
      }
      fout = fdopen(audio_fd, "w");
      if(!fout)
      {
        perror("Cannot open output");
        quit(1);
      }
#elif defined HAVE_LIBSNDIO
      struct sio_par par;

      hdl = sio_open(NULL, SIO_PLAY, 0);
      if (!hdl)
      {
         fprintf(stderr, "Cannot open sndio device\n");
         quit(1);
      }

      sio_initpar(&par);
      par.sig = 1;
      par.bits = 16;
      par.rate = rate;
      par.pchan = *channels;

      if (!sio_setpar(hdl, &par) || !sio_getpar(hdl, &par) ||
        par.sig != 1 || par.bits != 16 || par.rate != rate) {
          fprintf(stderr, "could not set sndio parameters\n");
          quit(1);
      }
      *channels = par.pchan;
      if (!sio_start(hdl)) {
          fprintf(stderr, "could not start sndio\n");
          quit(1);
      }
#elif defined HAVE_SYS_AUDIOIO_H
      audio_info_t info;
      int audio_fd;

      audio_fd = open("/dev/audio", O_WRONLY);
      if (audio_fd<0)
      {
         perror("Cannot open /dev/audio");
         quit(1);
      }

      AUDIO_INITINFO(&info);
#ifdef AUMODE_PLAY    /* NetBSD/OpenBSD */
      info.mode = AUMODE_PLAY;
#endif
      info.play.encoding = AUDIO_ENCODING_SLINEAR;
      info.play.precision = 16;
      info.play.input_sample_rate = rate;
      info.play.channels = *channels;

      if (ioctl(audio_fd, AUDIO_SETINFO, &info) < 0)
      {
         perror ("AUDIO_SETINFO");
         quit(1);
      }
      fout = fdopen(audio_fd, "w");
      if(!fout)
      {
        perror("Cannot open output");
        quit(1);
      }
#elif defined WIN32 || defined _WIN32
      {
         unsigned int opus_channels = *channels;
         if (Set_WIN_Params (INVALID_FILEDESC, rate, SAMPLE_SIZE, opus_channels))
         {
            fprintf (stderr, "Can't access %s\n", "WAVE OUT");
            quit(1);
         }
      }
#else
      fprintf (stderr, "No soundcard support\n");
      quit(1);
#endif
   } else {
      if (strcmp(outFile,"-")==0)
      {
#if defined WIN32 || defined _WIN32
         _setmode(_fileno(stdout), _O_BINARY);
#endif
         fout=stdout;
      }
      else
      {
         fout = fopen_utf8(outFile, "wb");
         if (!fout)
         {
            perror(outFile);
            quit(1);
         }
         if (*wav_format)
         {
            *wav_format = write_wav_header(fout, rate, mapping_family, *channels);
            if (*wav_format < 0)
            {
               fprintf (stderr, "Error writing WAV header.\n");
               quit(1);
            }
         }
      }
   }
   return fout;
}
Beispiel #13
0
UINT8 StartStream(UINT8 DeviceID)
{
    UINT32 RetVal;
#ifdef USE_LIBAO
    ao_sample_format ao_fmt;
#else
#ifdef WIN32
    UINT16 Cnt;
    HANDLE WaveOutThreadHandle;
    DWORD WaveOutThreadID;
    //char TestStr[0x80];
#elif defined(__NetBSD__)
    struct audio_info AudioInfo;
#else
    UINT32 ArgVal;
#endif
#endif	// ! USE_LIBAO

    if (WaveOutOpen)
        return 0xD0;	// Thread is already active

    // Init Audio
    WaveFmt.wFormatTag = WAVE_FORMAT_PCM;
    WaveFmt.nChannels = 2;
    WaveFmt.nSamplesPerSec = SampleRate;
    WaveFmt.wBitsPerSample = 16;
    WaveFmt.nBlockAlign = WaveFmt.wBitsPerSample * WaveFmt.nChannels / 8;
    WaveFmt.nAvgBytesPerSec = WaveFmt.nSamplesPerSec * WaveFmt.nBlockAlign;
    WaveFmt.cbSize = 0;
    if (DeviceID == 0xFF)
        return 0x00;

#if defined(WIN32) || defined(USE_LIBAO)
    BUFFERSIZE = SampleRate / 100 * SAMPLESIZE;
    if (BUFFERSIZE > BUFSIZE_MAX)
        BUFFERSIZE = BUFSIZE_MAX;
#else
    BUFFERSIZE = 1 << BUFSIZELD;
#endif
    SMPL_P_BUFFER = BUFFERSIZE / SAMPLESIZE;
    if (AUDIOBUFFERU > AUDIOBUFFERS)
        AUDIOBUFFERU = AUDIOBUFFERS;

    PauseThread = true;
    ThreadPauseConfrm = false;
    CloseThread = false;
    StreamPause = false;

#ifndef USE_LIBAO
#ifdef WIN32
    ThreadPauseEnable = true;
    WaveOutThreadHandle = CreateThread(NULL, 0x00, &WaveOutThread, NULL, 0x00,
                                       &WaveOutThreadID);
    if(WaveOutThreadHandle == NULL)
        return 0xC8;		// CreateThread failed
    CloseHandle(WaveOutThreadHandle);

    RetVal = waveOutOpen(&hWaveOut, ((UINT)DeviceID - 1), &WaveFmt, 0x00, 0x00, CALLBACK_NULL);
    if(RetVal != MMSYSERR_NOERROR)
#else
    ThreadPauseEnable = false;
#ifdef __NetBSD__
    hWaveOut = open("/dev/audio", O_WRONLY);
#else
    hWaveOut = open("/dev/dsp", O_WRONLY);
#endif
    if (hWaveOut < 0)
#endif
#else	// ifdef USE_LIBAO
    ao_initialize();

    ThreadPauseEnable = false;
    ao_fmt.bits = WaveFmt.wBitsPerSample;
    ao_fmt.rate = WaveFmt.nSamplesPerSec;
    ao_fmt.channels = WaveFmt.nChannels;
    ao_fmt.byte_format = AO_FMT_NATIVE;
    ao_fmt.matrix = NULL;

    dev_ao = ao_open_live(ao_default_driver_id(), &ao_fmt, NULL);
    if (dev_ao == NULL)
#endif
    {
        CloseThread = true;
        return 0xC0;		// waveOutOpen failed
    }
    WaveOutOpen = true;

    //sprintf(TestStr, "Buffer 0,0:\t%p\nBuffer 0,1:\t%p\nBuffer 1,0:\t%p\nBuffer 1,1:\t%p\n",
    //		&BufferOut[0][0], &BufferOut[0][1], &BufferOut[1][0], &BufferOut[1][1]);
    //AfxMessageBox(TestStr);
#ifndef USE_LIBAO
#ifdef WIN32
    for (Cnt = 0x00; Cnt < AUDIOBUFFERU; Cnt ++)
    {
        WaveHdrOut[Cnt].lpData = BufferOut[Cnt];	// &BufferOut[Cnt][0x00];
        WaveHdrOut[Cnt].dwBufferLength = BUFFERSIZE;
        WaveHdrOut[Cnt].dwBytesRecorded = 0x00;
        WaveHdrOut[Cnt].dwUser = 0x00;
        WaveHdrOut[Cnt].dwFlags = 0x00;
        WaveHdrOut[Cnt].dwLoops = 0x00;
        WaveHdrOut[Cnt].lpNext = NULL;
        WaveHdrOut[Cnt].reserved = 0x00;
        RetVal = waveOutPrepareHeader(hWaveOut, &WaveHdrOut[Cnt], sizeof(WAVEHDR));
        WaveHdrOut[Cnt].dwFlags |= WHDR_DONE;
    }
#elif defined(__NetBSD__)
    AUDIO_INITINFO(&AudioInfo);

    AudioInfo.mode = AUMODE_PLAY;
    AudioInfo.play.sample_rate = WaveFmt.nSamplesPerSec;
    AudioInfo.play.channels = WaveFmt.nChannels;
    AudioInfo.play.precision = WaveFmt.wBitsPerSample;
    AudioInfo.play.encoding = AUDIO_ENCODING_SLINEAR;

    RetVal = ioctl(hWaveOut, AUDIO_SETINFO, &AudioInfo);
    if (RetVal)
        printf("Error setting audio information!\n");
#else
    ArgVal = (AUDIOBUFFERU << 16) | BUFSIZELD;
    RetVal = ioctl(hWaveOut, SNDCTL_DSP_SETFRAGMENT, &ArgVal);
    if (RetVal)
        printf("Error setting Fragment Size!\n");
    ArgVal = AFMT_S16_NE;
    RetVal = ioctl(hWaveOut, SNDCTL_DSP_SETFMT, &ArgVal);
    if (RetVal)
        printf("Error setting Format!\n");
    ArgVal = WaveFmt.nChannels;
    RetVal = ioctl(hWaveOut, SNDCTL_DSP_CHANNELS, &ArgVal);
    if (RetVal)
        printf("Error setting Channels!\n");
    ArgVal = WaveFmt.nSamplesPerSec;
    RetVal = ioctl(hWaveOut, SNDCTL_DSP_SPEED, &ArgVal);
    if (RetVal)
        printf("Error setting Sample Rate!\n");
#endif
#endif	// USE_LIBAO

    if (SoundLog)
        SaveFile(0x00000000, NULL);

    PauseThread = false;

    return 0x00;
}
Beispiel #14
0
/** 
 * Open the specified device and check capability of the opening device.
 * 
 * @param devstr [in] device string to open
 * 
 * @return TRUE on success, FALSE on failure.
 */
static boolean
adin_mic_open(char *devstr)
{
  Audio_hdr Dev_hdr, old_hdr;
  double vol;

  /* open the device */
  if ((afd = open(devstr, O_RDONLY)) == -1) {
    if (errno == EBUSY) {
      jlog("Error: adin_sun4: audio device %s is busy\n", devstr);
      return(FALSE);
    } else {
      jlog("Error: adin_sun4: unable to open %s\n",devstr);
      return(FALSE);
    }
  }

  /* set recording port to microphone */
  AUDIO_INITINFO(&ainfo);
  ainfo.record.port = AUDIO_MICROPHONE;
  if (ioctl(afd, AUDIO_SETINFO, &ainfo) == -1) {
    jlog("Error: adin_sun4: failed to set recording port\n");
    return(FALSE);
  }

  /* set recording parameters */
  if (audio_get_record_config(afd, &Dev_hdr) != AUDIO_SUCCESS) {
    jlog("Error: adin_sun4: failed to get recording config\n"); return(FALSE);
  }
  Dev_hdr.sample_rate = srate;
  Dev_hdr.samples_per_unit = 1; /* ? I don't know this param. ? */
  Dev_hdr.bytes_per_unit = 2;
  Dev_hdr.channels = 1;
  Dev_hdr.encoding = AUDIO_ENCODING_LINEAR;
  if (audio_set_record_config(afd, &Dev_hdr) != AUDIO_SUCCESS) {
    jlog("Error: adin_sun4: failed to set recording config\n"); return(FALSE);
  }

  /* set volume */
  vol = (float)volume / (float)100;
  if (audio_set_record_gain(afd, &vol) != AUDIO_SUCCESS) {
    jlog("Error: adin_sun4: failed to set recording volume\n");
    return(FALSE);
  }

  /* flush buffer */
  if((ioctl(afd , I_FLUSH , FLUSHRW)) == -1) {
    jlog("Error: adin_sun4: cannot flush input buffer\n");
    return(FALSE);
  }
  
  /* setup polling */
  pfd.fd = afd;
  pfd.events = POLLIN;

#if 0
  /* pause transfer */
  if (audio_pause_record(afd) == AUDIO_ERR_NOEFFECT) {
    jlog("Error: adin_sun4: cannot pause audio\n");
    return(FALSE);
  }
#endif

  return(TRUE);
}
Beispiel #15
0
// **** Audio card support
// Aquire and enabled audio card
// return 0 if ok, -1 if failed
int HAE_AquireAudioCard(void *context, UINT32 sampleRate, UINT32 channels, UINT32 bits) {
    int flag;
    short int count;
    INT32 error;
    audio_info_t sunAudioHeader;
    char* pAudioDev = HAE_GetAudioDevPlay(g_currentDeviceID, 0);
	
    flag = 0;
    g_activeDoubleBuffer = FALSE;
    g_shutDownDoubleBuffer = TRUE;

    g_audioFramesToGenerate = HAE_GetMaxSamplePerSlice();	// get number of frames per sample rate slice

    // we're going to build this many buffers at a time
    g_synthFramesPerBlock = HAE_SOLARIS_FRAMES_PER_BLOCK;
    g_audioPeriodSleepTime = HAE_SOLARIS_SOUND_PERIOD;
    g_bitSize = bits;
    g_channels = channels;
    if (bits == 8) {
	g_audioByteBufferSize = ((INT32)sizeof(char) * g_audioFramesToGenerate);
    } else {
	g_audioByteBufferSize = ((INT32)sizeof(short int) * g_audioFramesToGenerate);
    }
    g_audioByteBufferSize *= channels;

    flag = 1;
    // allocate buffer blocks
    g_audioBufferBlock = HAE_Allocate(g_audioByteBufferSize * HAE_SOLARIS_FRAMES_PER_BLOCK);
    if (g_audioBufferBlock) {
	// try to open wave device
	// $$kk: 12.17.97: need O_NONBLOCK flag to be compatible with windows
#ifdef __linux__
            g_waveDevice = open(pAudioDev,O_WRONLY);
#else
            g_waveDevice = open(pAudioDev,O_WRONLY|O_NONBLOCK);
#endif

	if (g_waveDevice > 0) {

	    /* set to multiple open */
	    if (ioctl(g_waveDevice, AUDIO_MIXER_MULTIPLE_OPEN, NULL) >= 0) {
		TRACE1("HAE_AquireAudioCard: %s set to multiple open\n", pAudioDev);
	    } else {
		ERROR1("HAE_AquireAudioCard: ioctl AUDIO_MIXER_MULTIPLE_OPEN failed on %s!\n", pAudioDev);
	    }

	    AUDIO_INITINFO(&sunAudioHeader);
	    // $$kk: 12.17.97: need AUDIO_GETINFO ioctl to get this to work on solaris x86 
	    // add next 1 line
	    error = ioctl(g_waveDevice, AUDIO_GETINFO, &sunAudioHeader);

	    // $$kk: 03.16.98: not valid to call AUDIO_SETINFO ioctl with all the fields from AUDIO_GETINFO,
	    // so let's try init'ing again....
	    AUDIO_INITINFO(&sunAudioHeader);

	    // Set rendering format of the sun device.
	    sunAudioHeader.play.sample_rate = sampleRate;
	    sunAudioHeader.play.precision = bits;
	    sunAudioHeader.play.channels = channels;
	    sunAudioHeader.play.encoding = AUDIO_ENCODING_LINEAR;
		
	    error = ioctl(g_waveDevice, AUDIO_SETINFO, &sunAudioHeader);

	    if (error == 0) {
		g_shutDownDoubleBuffer = FALSE;
		g_activeDoubleBuffer = TRUE;	// must enable process, before thread begins


				/* Spin threads for device service and possibly
				 * stream service.
				 */
				// create thread to manage and render audio frames
		error = HAE_CreateFrameThread(context, PV_AudioWaveOutFrameThread);

		if (error == 0) {	// ok
		    flag = 0;
#ifdef USE_RAWDATA_CHECK
		    { 
			char* fname = "javasound_debug_output.pcm";
			debugrawfile = HAE_FileOpenForWrite(fname);
		    }
#endif

		} else {
		    flag = 1;
		    g_activeDoubleBuffer = FALSE;
		}
	    }
	}
    }

    if (flag) {	// something failed
	HAE_ReleaseAudioCard(context);
    }
    return flag;
}
Beispiel #16
0
static int sun_audio_getinfo(audio_info_t *auinfo)
{
    AUDIO_INITINFO(auinfo);
    return ioctl(audioctl_fd, AUDIO_GETINFO, auinfo);
}
Beispiel #17
0
struct sio_hdl *
_sio_sun_open(const char *str, unsigned int mode, int nbio)
{
	int fd, flags, fullduplex;
	struct audio_info aui;
	struct sio_sun_hdl *hdl;
	struct sio_par par;
	char path[PATH_MAX];

	switch (*str) {
	case '/':
	case ':': /* XXX: for backward compat */
		str++;
		break;
	default:
		DPRINTF("_sio_sun_open: %s: '/<devnum>' expected\n", str);
		return NULL;
	}
	hdl = malloc(sizeof(struct sio_sun_hdl));
	if (hdl == NULL)
		return NULL;
	_sio_create(&hdl->sio, &sio_sun_ops, mode, nbio);

	snprintf(path, sizeof(path), "/dev/audio%s", str);
	if (mode == (SIO_PLAY | SIO_REC))
		flags = O_RDWR;
	else
		flags = (mode & SIO_PLAY) ? O_WRONLY : O_RDONLY;

	while ((fd = open(path, flags | O_NONBLOCK)) < 0) {
		if (errno == EINTR)
			continue;
		DPERROR(path);
		goto bad_free;
	}
	if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) {
		DPERROR("FD_CLOEXEC");
		goto bad_close;
	}

	/*
	 * pause the device
	 */
	AUDIO_INITINFO(&aui);
	if (mode & SIO_PLAY)
		aui.play.pause = 1;
	if (mode & SIO_REC)
		aui.record.pause = 1;
	if (ioctl(fd, AUDIO_SETINFO, &aui) < 0) {
		DPERROR("sio_open_sun: setinfo");
		goto bad_close;
	}
	/*
	 * If both play and record are requested then
	 * set full duplex mode.
	 */
	if (mode == (SIO_PLAY | SIO_REC)) {
		fullduplex = 1;
		if (ioctl(fd, AUDIO_SETFD, &fullduplex) < 0) {
			DPRINTF("sio_open_sun: %s: can't set full-duplex\n", path);
			goto bad_close;
		}
	}
	hdl->fd = fd;

	/*
	 * Default parameters may not be compatible with libsndio (eg. mulaw
	 * encodings, different playback and recording parameters, etc...), so
	 * set parameters to a random value. If the requested parameters are
	 * not supported by the device, then sio_setpar() will pick supported
	 * ones.
	 */
	sio_initpar(&par);
	par.rate = 48000;
	par.le = SIO_LE_NATIVE;
	par.sig = 1;
	par.bits = 16;
	par.appbufsz = 1200;
	if (!sio_setpar(&hdl->sio, &par))
		goto bad_close;
	return (struct sio_hdl *)hdl;
 bad_close:
	while (close(fd) < 0 && errno == EINTR)
		; /* retry */
 bad_free:
	free(hdl);
	return NULL;
}
Beispiel #18
0
static int open_output(void)
{
    int include_enc = 0, exclude_enc = PE_BYTESWAP;
    struct stat sb;
    audio_info_t auinfo;
    char *audio_dev, *audio_ctl_dev, *tmp_audio;


    /* See if the AUDIODEV environment variable is defined, and set the
       audio device accordingly  - Lalit Chhabra 23/Oct/2001 */
    if((audio_dev  = getenv("AUDIODEV")) != NULL)
    {
      dpm.id_name = safe_malloc(strlen(audio_dev));
      dpm.name = safe_malloc(strlen(audio_dev));
      strcpy(dpm.name, audio_dev);
      strcpy(dpm.id_name, audio_dev);

      tmp_audio = safe_malloc(strlen(audio_dev) + 3);
      audio_ctl_dev = safe_malloc(strlen(audio_dev) + 3);

      strcpy(tmp_audio, audio_dev);
      strcpy(audio_ctl_dev, strcat(tmp_audio, "ctl"));
    }
    else
    {
      audio_ctl_dev = safe_malloc(strlen(AUDIO_CTLDEV) + 3);
      strcpy(audio_ctl_dev, AUDIO_CTLDEV);
    }

    output_counter = play_samples_offset = 0;

    /* Open the audio device */
    if((audioctl_fd = open(audio_ctl_dev, O_RDWR)) < 0)
    {
	ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
		  "%s: %s", audio_ctl_dev, strerror(errno));
	return -1;
    }

/* ############## */
#if 0
    if((dpm.fd = open(dpm.name, O_WRONLY | O_NDELAY)) == -1)
    {
	ctl->cmsg(CMSG_WARNING, VERB_NORMAL,
		  "%s: %s", dpm.name, strerror(errno));
	if(errno == EBUSY)
	{
	    if((dpm.fd = open(dpm.name, O_WRONLY)) == -1)
	    {
		ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
			  "%s: %s", dpm.name, strerror(errno));
		close_output();
		return -1;
	    }
	}
    }
#endif

    if((dpm.fd = open(dpm.name, O_WRONLY)) == -1)
    {
	ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
		  "%s: %s", dpm.name, strerror(errno));
	close_output();
	return -1;
    }

    if(stat(dpm.name, &sb) < 0)
    {
	ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
		  "%s: %s", dpm.name, strerror(errno));
	close_output();
	return -1;
    }

    if(!S_ISCHR(sb.st_mode))
    {
	ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
		  "%s: Not a audio device", dpm.name);
	close_output();
	return -1;
    }

    if(sun_audio_getinfo(&auinfo) < 0)
    { 
	/* from Francesco Zanichelli's */
	/* If it doesn't give info, it probably won't take requests
	    either. Assume it's an old device that does 8kHz uLaw only.

	      Disclaimer: I don't know squat about the various Sun audio
		  devices, so if this is not what we should do, I'll gladly
		      accept modifications. */
	ctl->cmsg(CMSG_WARNING, VERB_NORMAL, "Cannot inquire %s", dpm.name);
	include_enc = PE_ULAW|PE_ALAW|PE_MONO;
	exclude_enc = PE_SIGNED|PE_16BIT|PE_BYTESWAP;
	dpm.encoding = validate_encoding(dpm.encoding,
					 include_enc, exclude_enc);
	if(dpm.rate != 8000)
	    ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,
		      "Sample rate is changed %d to 8000",
		      dpm.rate);
	dpm.rate = 8000;
	return 1;
    }

    if(!(dpm.encoding & PE_16BIT))
	exclude_enc |= PE_SIGNED; /* Always unsigned */
    dpm.encoding = validate_encoding(dpm.encoding, include_enc, exclude_enc);

    AUDIO_INITINFO(&auinfo);
    auinfo.play.sample_rate = dpm.rate;
    auinfo.play.channels = (dpm.encoding & PE_MONO) ? 1 : 2;
    auinfo.play.encoding = sun_audio_encoding(dpm.encoding);
    auinfo.play.precision = (dpm.encoding & PE_16BIT) ? 16 : 8;

    if(sun_audio_setinfo(&auinfo) == -1)
    {
	ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
		  "rate=%d, channels=%d, precision=%d, encoding=%s",
		  auinfo.play.sample_rate, auinfo.play.channels,
		  auinfo.play.precision, output_encoding_string(dpm.encoding));
	close_output();
	return -1;
    }

    return 0;
}
Beispiel #19
0
// Aquire and enabled audio card
// return 0 if ok, -1 if failed
int HAE_AquireAudioCapture(void *context, UINT32 encoding, UINT32 sampleRate, UINT32 channels, UINT32 bits,
			   UINT32 audioFramesPerBuffer, UINT_PTR *pCaptureHandle) {
    audio_info_t sunAudioHeader;
    INT32 error = -1;
	
    char* pAudioDev = HAE_GetAudioDevRec(g_soundDeviceIndex, 0);
    INT32 minFramesPerBuffer;

    //fprintf(stderr, "Entering HAE_AquireAudioCapture(encoding=%d, samplerate=%d, channels=%d, bits=%d, framesPerBuffer=%d)\n", 
    //	encoding, sampleRate, channels, bits, audioFramesPerBuffer);

    g_encoding = encoding;
    g_bitSize = bits;
    g_channels = channels;
    g_sampleRate = sampleRate;	

    if( audioFramesPerBuffer == 0 ) {
	audioFramesPerBuffer = sampleRate * HAE_SOLARIS_DEFAULT_BUFFERSIZE_IN_MS / 1000;
    }

    g_audioFramesToRead = audioFramesPerBuffer / g_audioCaptureBufferSizeDivisor;

    if (pCaptureHandle) {
	*pCaptureHandle = 0L;
    }

    // try to open wave device for recording
    // $$kk: 12.17.97: need O_NONBLOCK flag to be compatible with windows

    // $$kk: 10.13.98: we want O_NONBLOCK so that we return failure immediately if the
    // device is busy (or absent or whatever) rather than blocking.  however, i think that
    // this same O_NONBLOCK flag dictates whether the read() calls should block.  even 
    // without the O_NONBLOCK flag set, read() does *not* block for me, so i'm keeping 
    // the flag for now....
	
    g_captureSound = open(pAudioDev,O_RDONLY|O_NONBLOCK);

    if (g_captureSound > 0) {

	/* set to multiple open */
	if (ioctl(g_captureSound, AUDIO_MIXER_MULTIPLE_OPEN, NULL) >= 0) {
	    TRACE1("HAE_AquireAudioCapture: %s set to multiple open\n", pAudioDev);
	} else {
	    ERROR1("HAE_AquireAudioCapture: ioctl AUDIO_MIXER_MULTIPLE_OPEN failed on %s!\n", pAudioDev);
	}

	AUDIO_INITINFO(&sunAudioHeader);
		
	// Set capture format of the sun device.
	sunAudioHeader.record.sample_rate = sampleRate;
	sunAudioHeader.record.precision = bits;
	sunAudioHeader.record.channels = channels;
	sunAudioHeader.record.buffer_size = g_audioFramesToRead * channels * bits / 8;
		
	sunAudioHeader.record.encoding = AUDIO_ENCODING_LINEAR;
	if (g_encoding == ULAW) {
	    sunAudioHeader.record.encoding = AUDIO_ENCODING_ULAW;			
	} 
	else if (g_encoding == ALAW) {
	    sunAudioHeader.record.encoding = AUDIO_ENCODING_ALAW;			
	} 



	// start out paused so we don't overflow the device driver buffers
	sunAudioHeader.record.pause = 1;
	error = ioctl(g_captureSound, AUDIO_SETINFO, &sunAudioHeader);

	if (error != -1) {
	    // flush anything we might have accumulated in the capture queue before pausing
	    error = ioctl(g_captureSound, I_FLUSH, FLUSHR);

	    error = ioctl(g_captureSound, AUDIO_GETINFO, &sunAudioHeader);
	    g_audioFramesToRead = sunAudioHeader.record.buffer_size / (channels * bits / 8);


	    if (error != -1) {
		if (pCaptureHandle) {
		    *pCaptureHandle = (UINT_PTR)g_captureSound;
		}
	    } 
	}
    }

    if (error == -1) {	// something failed
	HAE_ReleaseAudioCapture(context);
    }

    //fprintf(stderr, "<< HAE_API_SolarisOS_Capture: HAE_AquireAudioCapture() returning %d\n", error);
    return error;
}
Beispiel #20
0
static BOOL Sun_Init(void)
{
	int play_stereo, play_rate;
#ifdef SUNOS4
	int audiotype;
#else
	audio_device_t audiotype;
#endif
	struct audio_info audioinfo;

	if (getenv("AUDIODEV"))
		sndfd = open(getenv("AUDIODEV"), O_WRONLY);
	else {
		sndfd = open(SOUNDDEVICE, O_WRONLY);
#if defined __NetBSD__ || defined __OpenBSD__
		if (sndfd < 0)
			sndfd = open(SOUNDDEVICE "0", O_WRONLY);
#endif
	}
	if (sndfd < 0) {
		_mm_errno = MMERR_OPENING_AUDIO;
		return 1;
	}

	if (!(audiobuffer = (SBYTE *)_mm_malloc(fragsize)))
		return 1;

	play_precision = (md_mode & DMODE_16BITS) ? 16 : 8;
	play_stereo = (md_mode & DMODE_STEREO) ? 2 : 1;
	play_rate = md_mixfreq;
	/* attempt to guess the encoding */
	play_encoding = -1;

	if (ioctl(sndfd, AUDIO_GETDEV, &audiotype) < 0) {
#ifdef MIKMOD_DEBUG
		fputs("\rSun driver warning: could not determine audio device type\n",
			  stderr);
#endif
	} else {
#if defined SUNOS4				/* SunOS 4 */
		switch (audiotype) {
		  case AUDIO_DEV_AMD:
			/* AMD 79C30 */
			/* 8bit mono ulaw 8kHz */
		  	play_rate = md_mixfreq = 8000;
			md_mode &= ~(DMODE_STEREO | DMODE_16BITS);
			play_precision = 8;
			play_stereo = 1;
			play_encoding = AUDIO_ENCODING_ULAW;
			break;
		  case AUDIO_DEV_SPEAKERBOX:
		  case AUDIO_DEV_CODEC:
			/* CS 4231 or DBRI or speaker box */
			/* 16bit mono/stereo linear 8kHz - 48kHz */
			if (play_precision == 16)
				play_encoding = AUDIO_ENCODING_LINEAR;
			/* 8bit mono ulaw 8kHz - 48kHz */
			else if (play_precision == 8) {
				md_mode &= ~(DMODE_STEREO);
				play_stereo = 1;
				play_encoding = AUDIO_ENCODING_ULAW;
			} else {
				_mm_errno = MMERR_SUN_INIT;
				return 1;
			}
			break;
		}
#elif defined SOLARIS			/* Solaris */
		if (!strcmp(audiotype.name, "SUNW,am79c30")) {
			/* AMD 79C30 */
			/* 8bit mono ulaw 8kHz */
		  	play_rate = md_mixfreq = 8000;
			md_mode &= ~(DMODE_STEREO | DMODE_16BITS);
			play_precision = 8;
			play_stereo = 1;
			play_encoding = AUDIO_ENCODING_ULAW;
		} else
			if ((!strcmp(audiotype.name, "SUNW,CS4231")) ||
				(!strcmp(audiotype.name, "SUNW,dbri")) ||
				(!strcmp(audiotype.name, "speakerbox"))) {
			/* CS 4231 or DBRI or speaker box */
			/* 16bit mono/stereo linear 8kHz - 48kHz */
			if (play_precision == 16)
				play_encoding = AUDIO_ENCODING_LINEAR;
			/* 8bit mono ulaw 8kHz - 48kHz */
			else if (play_precision == 8) {
				md_mode &= ~(DMODE_STEREO);
				play_stereo = 1;
				play_encoding = AUDIO_ENCODING_ULAW;
			} else {
				_mm_errno = MMERR_SUN_INIT;
				return 1;
			}
		}
#else /* NetBSD, OpenBSD */
		if (!strcmp(audiotype.name, "amd7930")) {
			/* AMD 79C30 */
			/* 8bit mono ulaw 8kHz */
		  	play_rate = md_mixfreq = 8000;
			md_mode &= ~(DMODE_STEREO | DMODE_16BITS);
			play_precision = 8;
			play_stereo = 1;
			play_encoding = AUDIO_ENCODING_ULAW;
		}
		if ((!strcmp(audiotype.name, "Am78C201")) ||
			(!strcmp(audiotype.name, "UltraSound")) 
		   ) {
			/* Gravis UltraSound, AMD Interwave and compatible cards */
			/* 16bit stereo linear 44kHz */
		  	play_rate = md_mixfreq = 44100;
			md_mode |= (DMODE_STEREO | DMODE_16BITS);
			play_precision = 16;
			play_stereo = 2;
			play_encoding = AUDIO_ENCODING_SLINEAR;
		}
#endif
	}

	/* Sound devices which were not handled above don't have specific
	   limitations, so try and guess optimal settings */
	if (play_encoding == -1) {
		if ((play_precision == 8) && (play_stereo == 1) &&
			(play_rate <= 8000)) play_encoding = AUDIO_ENCODING_ULAW;
		else
#ifdef SUNOS4
			play_encoding = AUDIO_ENCODING_LINEAR;
#else
			play_encoding =
				(play_precision ==
				 16) ? AUDIO_ENCODING_SLINEAR : AUDIO_ENCODING_ULINEAR;
#endif
	}

	/* get current audio settings if we want to keep the playback output
	   port */
	if (!port) {
		AUDIO_INITINFO(&audioinfo);
		if (ioctl(sndfd, AUDIO_GETINFO, &audioinfo) < 0) {
			_mm_errno = MMERR_SUN_INIT;
			return 1;
		}
		port = audioinfo.play.port;
	}

	AUDIO_INITINFO(&audioinfo);
	audioinfo.play.precision = play_precision;
	audioinfo.play.channels = play_stereo;
	audioinfo.play.sample_rate = play_rate;
	audioinfo.play.encoding = play_encoding;
	audioinfo.play.port = port;
#if defined __NetBSD__ || defined __OpenBSD__
#if defined AUMODE_PLAY_ALL
	audioinfo.mode = AUMODE_PLAY | AUMODE_PLAY_ALL;
#else
	audioinfo.mode = AUMODE_PLAY;
#endif
#endif

	if (ioctl(sndfd, AUDIO_SETINFO, &audioinfo) < 0) {
		_mm_errno = MMERR_SUN_INIT;
		return 1;
	}

	/* check if our changes were accepted */
	if (ioctl(sndfd, AUDIO_GETINFO, &audioinfo) < 0) {
		_mm_errno = MMERR_SUN_INIT;
		return 1;
	}
	if ((audioinfo.play.precision != play_precision) ||
		(audioinfo.play.channels != play_stereo) ||
		(normalize(audioinfo.play.encoding) != normalize(play_encoding))) {
		_mm_errno = MMERR_SUN_INIT;
		return 1;
	}

	if (audioinfo.play.sample_rate != play_rate) {
		/* Accept a shift inferior to 5% of the expected rate */
		int delta = audioinfo.play.sample_rate - play_rate;

		if (delta < 0)
			delta = -delta;

		if (delta * 20 > play_rate) {
			_mm_errno = MMERR_SUN_INIT;
			return 1;
		}
		/* Align to what the card gave us */
		md_mixfreq = audioinfo.play.sample_rate;
	}

	return VC_Init();
}
Beispiel #21
0
static void
solaris_play (int argc, char *argv [])
{	static short 	buffer [BUFFER_LEN] ;
	audio_info_t	audio_info ;
	SNDFILE			*sndfile ;
	SF_INFO			sfinfo ;
	unsigned long	delay_time ;
	long			k, start_count, output_count, write_count, read_count ;
	int				audio_fd, error, done ;

	for (k = 1 ; k < argc ; k++)
	{	printf ("Playing %s\n", argv [k]) ;
		if (! (sndfile = sf_open (argv [k], SFM_READ, &sfinfo)))
		{	puts (sf_strerror (NULL)) ;
			continue ;
			} ;

		if (sfinfo.channels < 1 || sfinfo.channels > 2)
		{	printf ("Error : channels = %d.\n", sfinfo.channels) ;
			continue ;
			} ;

		/* open the audio device - write only, non-blocking */
		if ((audio_fd = open ("/dev/audio", O_WRONLY | O_NONBLOCK)) < 0)
		{	perror ("open (/dev/audio) failed") ;
			return ;
			} ;

		/*	Retrive standard values. */
		AUDIO_INITINFO (&audio_info) ;

		audio_info.play.sample_rate = sfinfo.samplerate ;
		audio_info.play.channels = sfinfo.channels ;
		audio_info.play.precision = 16 ;
		audio_info.play.encoding = AUDIO_ENCODING_LINEAR ;
		audio_info.play.gain = AUDIO_MAX_GAIN ;
		audio_info.play.balance = AUDIO_MID_BALANCE ;

		if ((error = ioctl (audio_fd, AUDIO_SETINFO, &audio_info)))
		{	perror ("ioctl (AUDIO_SETINFO) failed") ;
			return ;
			} ;

		/* Delay time equal to 1/4 of a buffer in microseconds. */
		delay_time = (BUFFER_LEN * 1000000) / (audio_info.play.sample_rate * 4) ;

		done = 0 ;
		while (! done)
		{	read_count = sf_read_short (sndfile, buffer, BUFFER_LEN) ;
			if (read_count < BUFFER_LEN)
			{	memset (&(buffer [read_count]), 0, (BUFFER_LEN - read_count) * sizeof (short)) ;
				/* Tell the main application to terminate. */
				done = SF_TRUE ;
				} ;

			start_count = 0 ;
			output_count = BUFFER_LEN * sizeof (short) ;

			while (output_count > 0)
			{	/* write as much data as possible */
				write_count = write (audio_fd, &(buffer [start_count]), output_count) ;
				if (write_count > 0)
				{	output_count -= write_count ;
					start_count += write_count ;
					}
				else
				{	/*	Give the audio output time to catch up. */
					usleep (delay_time) ;
					} ;
				} ; /* while (outpur_count > 0) */
			} ; /* while (! done) */

		close (audio_fd) ;
		} ;

	return ;
} /* solaris_play */
Beispiel #22
0
/*
==============
SNDDMA_Submit
	
Send sound to device if buffer isn't really the dma buffer
===============
*/
void SNDDMA_Submit(void){
	int samplebytes = dma.samplebits / 8;
	audio_info_t au_info;
	int s_pos;
	int chunk_idx;
	static int last_chunk_idx = -1;
	
	if(!snd_inited)
		return;
		
	if(last_chunk_idx == -1){
		if(write(audio_fd, dma.buffer, dma.samples * samplebytes) != dma.samples * samplebytes)
			Com_Printf("initial write on audio device failed\n");
		last_chunk_idx = 0;
		dma.samplepos = 0;
		return;
	}
	
	if(ioctl(audio_fd, AUDIO_GETINFO, &au_info) == -1){
		Com_Printf("AUDIO_GETINFO failed: %s\n", strerror(errno));
		return;
	}
	
	if(au_info.play.error){
	
		/*
		 * underflow? clear the error flag and reset the HW sample counter
		 * and send the whole dma_buffer, to get sound output working again
		 */
		
		DPRINTF("audio data underflow\n");
		
		AUDIO_INITINFO(&au_info);
		au_info.play.error = 0;
		au_info.play.samples = 0;
		ioctl(audio_fd, AUDIO_SETINFO, &au_info);
		
		if(write(audio_fd, dma.buffer, dma.samples * samplebytes) != dma.samples * samplebytes)
			Com_Printf("refill sound driver after underflow failed\n");
		last_chunk_idx = 0;
		dma.samplepos = 0;
		return;
	}
	
	s_pos = au_info.play.samples * dma.channels;
	chunk_idx =(s_pos % dma.samples) / dma.submission_chunk;
	
	DPRINTF("HW DMA Pos=%u(%u), dma.samplepos=%u, play in=%d, last=%d\n",
			au_info.play.samples, s_pos, dma.samplepos,
			chunk_idx, last_chunk_idx);
	        
	while(chunk_idx != last_chunk_idx){
	
		if(write(audio_fd,
				  dma.buffer + dma.samplepos * samplebytes,
				  dma.submission_chunk * samplebytes) != dma.submission_chunk * samplebytes){
			Com_Printf("write error on audio device\n");
		}
		
		if((dma.samplepos += dma.submission_chunk) >= dma.samples)
			dma.samplepos = 0;
			
		if(++last_chunk_idx >= QSND_NUM_CHUNKS)
			last_chunk_idx = 0;
	}
}
Beispiel #23
0
qboolean
SNDDMA_Init ( void )
{
	if (snd_inited) {
		printf("Sound already init'd\n");
		return 0;
	}

	shm = &sn;
	shm->splitbuffer = 0;

	audio_fd = open("/dev/audio", O_WRONLY|O_NDELAY);

	if (audio_fd < 0) {
		if (errno == EBUSY) {
			Con_Printf("Audio device is being used by another process\n");
		}
		perror("/dev/audio");
		Con_Printf("Could not open /dev/audio\n");
		return (0);
	}

	if (ioctl(audio_fd, AUDIO_GETINFO, &info) < 0) {
		perror("/dev/audio");
		Con_Printf("Could not communicate with audio device.\n");
		close(audio_fd);
		return 0;
	}

	//
	// set to nonblock
	//
	if (fcntl(audio_fd, F_SETFL, O_NONBLOCK) < 0) {
		perror("/dev/audio");
		close(audio_fd);
		return 0;
	}

	AUDIO_INITINFO(&info);

	shm->speed = 11025;

	// try 16 bit stereo
	info.play.encoding = AUDIO_ENCODING_LINEAR;
	info.play.sample_rate = 11025;
	info.play.channels = 2;
	info.play.precision = 16;

	if (ioctl(audio_fd, AUDIO_SETINFO, &info) < 0) {
		info.play.encoding = AUDIO_ENCODING_LINEAR;
		info.play.sample_rate = 11025;
		info.play.channels = 1;
		info.play.precision = 16;
		if (ioctl(audio_fd, AUDIO_SETINFO, &info) < 0) {
			Con_Printf("Incapable sound hardware.\n");
			close(audio_fd);
			return 0;
		}
		Con_Printf("16 bit mono sound initialized\n");
		shm->samplebits = 16;
		shm->channels = 1;
	} else { // 16 bit stereo
		Con_Printf("16 bit stereo sound initialized\n");
		shm->samplebits = 16;
		shm->channels = 2;
	}

	shm->soundalive = true;
	shm->samples = sizeof(dma_buffer) / (shm->samplebits/8);
	shm->samplepos = 0;
	shm->submission_chunk = 1;
	shm->buffer = (unsigned char *)dma_buffer;

	snd_inited = 1;

	return 1;
}
Beispiel #24
0
/*
==================
SNDDMA_Init
 
Try to find a sound device to mix for.
Returns false if nothing is found.
Returns true and fills in the "dma" structure with information for the mixer.
==================
*/
qboolean SNDDMA_Init(struct sndinfo * s){
	int i;
	int samples;
	audio_info_t au_info;
	
	if(snd_inited)
		return 1;
		
	snd_inited = 0;
	
	si = s;
	
	// open /dev/audio
	
	if(audio_fd < 0){
	
		audio_fd = open(si->device->string, O_WRONLY);
		
		if(audio_fd < 0){
			Com_Printf("Could not open %s: %s\n", si->device->string, strerror(errno));
			return 0;
		}
	}
	
	// set sample bits & speed
	
	if((int)si->speed->value > 0){
		AUDIO_INITINFO(&au_info);
		
		au_info.play.precision =(int)si->bits->value;
		au_info.play.encoding =
			( au_info.play.precision == 8
			  ? AUDIO_ENCODING_LINEAR8
			  : AUDIO_ENCODING_LINEAR);
		au_info.play.sample_rate =(int)si->speed->value;
		au_info.play.channels =(int)sndchannels->value;
		
		if(ioctl(audio_fd, AUDIO_SETINFO, &au_info) == -1){
			Com_Printf("AUDIO_SETINFO failed: %s\n", strerror(errno));
			return 0;
		}
	} else {
		for(i = 0; i < sizeof(tryrates) / sizeof(tryrates[0]); i++){
			AUDIO_INITINFO(&au_info);
			
			au_info.play.precision =(int)si->bits->value;
			au_info.play.encoding =
				( au_info.play.precision == 8
				  ? AUDIO_ENCODING_LINEAR8
				  : AUDIO_ENCODING_LINEAR);
			au_info.play.sample_rate = tryrates[i];
			au_info.play.channels =(int)sndchannels->value;
			
			if(ioctl(audio_fd, AUDIO_SETINFO, &au_info) == 0)
				break;
				
			Com_Printf("AUDIO_SETINFO failed: %s\n", strerror(errno));
		}
		if(i >= sizeof(tryrates) / sizeof(tryrates[0]))
			return 0;
	}
	dma.samplebits = au_info.play.precision;
	dma.channels = au_info.play.channels;
	dma.speed = au_info.play.sample_rate;
	
	/*
	 * submit some sound data every ~ 0.1 seconds, and try to buffer 2*0.1 
	 * seconds in sound driver
	 */
	samples = dma.channels * dma.speed / 10;
	for(i = 0;(1 << i) < samples; i++)
		;
	dma.submission_chunk = 1 <<(i - 1);
	DPRINTF("channels %d, speed %d, log2(samples) %d, submission chunk %d\n",
			dma.channels, dma.speed, i - 1,
			dma.submission_chunk);
	        
	dma.samples = QSND_NUM_CHUNKS * dma.submission_chunk;
	dma.buffer = calloc(dma.samples, dma.samplebits / 8);
	if(dma.buffer == NULL){
		Com_Printf("Could not alloc sound buffer\n");
		return 0;
	}
	
	AUDIO_INITINFO(&au_info);
	au_info.play.eof = 0;
	au_info.play.samples = 0;
	ioctl(audio_fd, AUDIO_SETINFO, &au_info);
	
	dma.samplepos = 0;
	
	snd_inited = 1;
	
	return 1;
}
Beispiel #25
0
/*
 * audio_init - open and initialize audio device
 *
 * This code works with SunOS 4.x, Solaris 2.x, and PCM; however, it is
 * believed generic and applicable to other systems with a minor twid
 * or two. All it does is open the device, set the buffer size (Solaris
 * only), preset the gain and set the input port. It assumes that the
 * codec sample rate (8000 Hz), precision (8 bits), number of channels
 * (1) and encoding (ITU-T G.711 mu-law companded) have been set by
 * default.
 */
int
audio_init(
	const char *dname,	/* device name */
	int	bufsiz,		/* buffer size */
	int	unit		/* device unit (0-3) */
	)
{
#ifdef PCM_STYLE_SOUND
# define ACTL_DEV	"/dev/mixer%d"
	char actl_dev[30];
# ifdef HAVE_STRUCT_SND_SIZE
	struct snd_size s_size;
# endif
# ifdef AIOGFMT
	snd_chan_param s_c_p;
# endif
#endif
	int fd;
	int rval;
	const char *actl =
#ifdef PCM_STYLE_SOUND
		actl_dev
#else
		"/dev/audioctl"
#endif
		;

#ifdef PCM_STYLE_SOUND
	snprintf(actl_dev, sizeof(actl_dev), ACTL_DEV, unit);

	audio_config_read(unit, &actl, &dname);
	/* If we have values for cf_c_dev or cf_i_dev, use them. */
	if (*cf_c_dev)
		actl = cf_c_dev;
	if (*cf_i_dev)
		dname = cf_i_dev;
#endif

	/*
	 * Open audio device
	 */
	fd = open(dname, O_RDWR | O_NONBLOCK, 0777);
	if (fd < 0) {
		msyslog(LOG_ERR, "audio_init: %s %m", dname);
		return (fd);
	}

	/*
	 * Open audio control device.
	 */
	ctl_fd = open(actl, O_RDWR);
	if (ctl_fd < 0) {
		msyslog(LOG_ERR, "audio_init: invalid control device <%s>",
		    actl);
		close(fd);
		return(ctl_fd);
	}

	/*
	 * Set audio device parameters.
	 */
#ifdef PCM_STYLE_SOUND
	printf("audio_init: <%s> bufsiz %d\n", dname, bufsiz);
	rval = fd;

# ifdef HAVE_STRUCT_SND_SIZE
	if (ioctl(fd, AIOGSIZE, &s_size) == -1)
	    printf("audio_init: AIOGSIZE: %s\n", strerror(errno));
	else
	    printf("audio_init: orig: play_size %d, rec_size %d\n",
		s_size.play_size, s_size.rec_size);

	s_size.play_size = s_size.rec_size = bufsiz;
	printf("audio_init: want: play_size %d, rec_size %d\n",
	       s_size.play_size, s_size.rec_size);

	if (ioctl(fd, AIOSSIZE, &s_size) == -1)
	    printf("audio_init: AIOSSIZE: %s\n", strerror(errno));
	else
	    printf("audio_init: set:  play_size %d, rec_size %d\n",
		s_size.play_size, s_size.rec_size);
# endif /* HAVE_STRUCT_SND_SIZE */

# ifdef SNDCTL_DSP_SETFRAGMENT
	{
		int tmp = (16 << 16) + 6; /* 16 fragments, each 2^6 bytes */
		if (ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &tmp) == -1)
		    printf("audio_init: SNDCTL_DSP_SETFRAGMENT: %s\n",
			   strerror(errno));
	}
# endif /* SNDCTL_DSP_SETFRAGMENT */

# ifdef AIOGFMT
	if (ioctl(fd, AIOGFMT, &s_c_p) == -1)
	    printf("audio_init: AIOGFMT: %s\n", strerror(errno));
	else
	    printf("audio_init: play_rate %lu, rec_rate %lu, play_format %#lx, rec_format %#lx\n",
		s_c_p.play_rate, s_c_p.rec_rate, s_c_p.play_format, s_c_p.rec_format);
# endif

	/* Grab the device and record masks */

	if (ioctl(ctl_fd, SOUND_MIXER_READ_DEVMASK, &devmask) == -1)
	    printf("SOUND_MIXER_READ_DEVMASK: %s\n", strerror(errno));
	if (ioctl(ctl_fd, SOUND_MIXER_READ_RECMASK, &recmask) == -1)
	    printf("SOUND_MIXER_READ_RECMASK: %s\n", strerror(errno));

	/* validate and set any specified config file stuff */
	if (cf_agc[0] != '\0') {
		int i;

		/* recmask */
		i = mixer_name(cf_agc, recmask);
		if (i >= 0)
			agc = MIXER_WRITE(i);
		else
			printf("input %s not in recmask %#x\n",
			       cf_agc, recmask);
	}

	if (cf_monitor[0] != '\0') {
		int i;

		/* devmask */
		i = mixer_name(cf_monitor, devmask);
		if (i >= 0)
			monitor = MIXER_WRITE(i);
		else
			printf("monitor %s not in devmask %#x\n",
			       cf_monitor, devmask);
	}

#else /* not PCM_STYLE_SOUND */
	AUDIO_INITINFO(&info);
	info.play.gain = AUDIO_MAX_GAIN;
	info.play.port = AUDIO_SPEAKER;
# ifdef HAVE_SYS_AUDIOIO_H
	info.record.buffer_size = bufsiz;
# endif /* HAVE_SYS_AUDIOIO_H */
	rval = ioctl(ctl_fd, (int)AUDIO_SETINFO, (char *)&info);
	if (rval < 0) {
		msyslog(LOG_ERR, "audio: invalid control device parameters");
		close(ctl_fd);
		close(fd);
		return(rval);
	}
	rval = fd;
#endif /* not PCM_STYLE_SOUND */
	return (rval);
}
static gboolean
gst_sunaudiosink_prepare (GstAudioSink * asink, GstRingBufferSpec * spec)
{
  GstSunAudioSink *sunaudiosink = GST_SUNAUDIO_SINK (asink);
  audio_info_t ainfo;
  int ret;
  int ports;

  ret = ioctl (sunaudiosink->fd, AUDIO_GETINFO, &ainfo);
  if (ret == -1) {
    GST_ELEMENT_ERROR (sunaudiosink, RESOURCE, SETTINGS, (NULL), ("%s",
            strerror (errno)));
    return FALSE;
  }

  if (spec->width != 16)
    return FALSE;

  ports = ainfo.play.port;

  AUDIO_INITINFO (&ainfo);

  ainfo.play.sample_rate = spec->rate;
  ainfo.play.channels = spec->channels;
  ainfo.play.precision = spec->width;
  ainfo.play.encoding = AUDIO_ENCODING_LINEAR;
  ainfo.play.port = ports;

  /* buffer_time for playback is not implemented in Solaris at the moment,
     but at some point in the future, it might be */
  ainfo.play.buffer_size =
      gst_util_uint64_scale (spec->rate * spec->bytes_per_sample,
      spec->buffer_time, GST_SECOND / GST_USECOND);

  spec->silence_sample[0] = 0;
  spec->silence_sample[1] = 0;
  spec->silence_sample[2] = 0;
  spec->silence_sample[3] = 0;

  ret = ioctl (sunaudiosink->fd, AUDIO_SETINFO, &ainfo);
  if (ret == -1) {
    GST_ELEMENT_ERROR (sunaudiosink, RESOURCE, SETTINGS, (NULL), ("%s",
            strerror (errno)));
    return FALSE;
  }

  /* Now read back the info to find out the actual buffer size and set 
     segtotal */
  AUDIO_INITINFO (&ainfo);

  ret = ioctl (sunaudiosink->fd, AUDIO_GETINFO, &ainfo);
  if (ret == -1) {
    GST_ELEMENT_ERROR (sunaudiosink, RESOURCE, SETTINGS, (NULL), ("%s",
            strerror (errno)));
    return FALSE;
  }
#if 0
  /* We don't actually use the buffer_size from the sound device, because
   * it seems it's just bogus sometimes */
  sunaudiosink->segtotal = spec->segtotal =
      ainfo.play.buffer_size / spec->segsize;
#else
  sunaudiosink->segtotal = spec->segtotal;
#endif
  sunaudiosink->segtotal_samples =
      spec->segtotal * spec->segsize / spec->bytes_per_sample;

  sunaudiosink->segs_written = (gint) ainfo.play.eof;
  sunaudiosink->samples_written = ainfo.play.samples;
  sunaudiosink->bytes_per_sample = spec->bytes_per_sample;

  GST_DEBUG_OBJECT (sunaudiosink, "Got device buffer_size of %u",
      ainfo.play.buffer_size);

  return TRUE;
}
static int setaudio(struct xmp_options *o)
{
	audio_info_t ainfo, ainfo2;
	int gain;
	int bsize = 32 * 1024;
	int port;
	char *token, **parm;
	AUDIO_INITINFO(&ainfo);

	/* try to open audioctl device */
	if ((audioctl_fd = open("/dev/audioctl", O_RDWR)) < 0) {
		fprintf(stderr, "couldn't open audioctl device\n");
		close(audio_fd);
		return -1;
	}

	/* sleep(2); -- Really needed? */

	/* empty buffers before change config */
	ioctl(audio_fd, AUDIO_DRAIN, 0);	/* drain everything out */
	ioctl(audio_fd, I_FLUSH, FLUSHRW);	/* flush everything     */
	ioctl(audioctl_fd, I_FLUSH, FLUSHRW);	/* flush everything */

	/* get audio parameters. */
	if (ioctl(audioctl_fd, AUDIO_GETINFO, &ainfo) < 0) {
		fprintf(stderr, "AUDIO_GETINFO failed!\n");
		close(audio_fd);
		close(audioctl_fd);
		return -1;
	}

	close(audioctl_fd);

	/* KH: Sun Dbri doesn't support 8bits linear. I dont muck with the gain
	 *     or the port setting. I hate when a program does that. There is
	 *     nothing more frustrating then having a program change your volume
	 *     and change from external speakers to the tiny one
	 */

	gain = ainfo.play.gain;
	port = ainfo.play.port;

	parm_init();
	chkparm1("gain", gain = strtoul(token, NULL, 0));
	chkparm1("buffer", bsize = strtoul(token, NULL, 0));
	chkparm1("port", port = (int)*token)
	    parm_end();

	switch (port) {
	case 'h':
		port = AUDIO_HEADPHONE;
		break;
	case 'l':
		port = AUDIO_LINE_OUT;
		break;
	case 's':
		port = AUDIO_SPEAKER;
	}

	if (gain < AUDIO_MIN_GAIN)
		gain = AUDIO_MIN_GAIN;
	if (gain > AUDIO_MAX_GAIN)
		gain = AUDIO_MAX_GAIN;

	AUDIO_INITINFO(&ainfo);	/* For CS4231 */
	AUDIO_INITINFO(&ainfo2);	/* For AMD 7930 if needed */

	ainfo.play.sample_rate = o->freq;
	ainfo.play.channels = o->outfmt & XMP_FMT_MONO ? 1 : 2;
	ainfo.play.precision = o->resol;
	ainfo.play.encoding = AUDIO_ENCODING_LINEAR;
	ainfo2.play.gain = ainfo.play.gain = gain;
	ainfo2.play.port = ainfo.play.port = port;
	ainfo2.play.buffer_size = ainfo.play.buffer_size = bsize;

	if (ioctl(audio_fd, AUDIO_SETINFO, &ainfo) == -1) {
		/* CS4231 initialization Failed, perhaps we have an AMD 7930 */
		if (ioctl(audio_fd, AUDIO_SETINFO, &ainfo2) == -1) {
			close(audio_fd);
			return XMP_ERR_DINIT;
		}

		o->resol = 0;
		o->freq = 8000;
		o->outfmt |= XMP_FMT_MONO;
		drv_solaris.description = "Solaris AMD7930 PCM audio";
	} else {
		drv_solaris.description = "Solaris CS4231 PCM audio";
	}

	return 0;
}
Beispiel #28
0
// $$kk: 08.12.98 merge: changed this method to do convert to unsigned data if required by audio hardware 
void PV_AudioWaveOutFrameThread(void* context) {
    audio_info_t sunAudioHeader;
    char *pFillBuffer;
    INT32 count, currentPos, lastPos, sampleFrameSize;
    UINT32 startTime, stopTime, fillTime;
    int i;
    int rc;
    int bytesWritten;
    int bytesToWrite;


    ioctl(g_waveDevice, AUDIO_GETINFO, &sunAudioHeader);

    // calculate sample size for convertion of bytes to sample frames
    sampleFrameSize = 1;
		
    if (g_bitSize == 16) {
	sampleFrameSize *= 2;
    }

    if (g_channels == 2) {
	sampleFrameSize *= 2;
    }


    lastPos = sunAudioHeader.play.samples - ((g_audioByteBufferSize * HAE_SOLARIS_FRAMES_PER_BLOCK * 2) / sampleFrameSize);

    if (g_audioBufferBlock) {
	while ( (g_activeDoubleBuffer) && (g_shutDownDoubleBuffer == FALSE) ) {

	    /* put sync count and XMicroseconds into relation */
	    /* could be improved by using actual device sample count */
	    g_checkpointMicros = XMicroseconds();
	    g_checkpointSyncCount = GM_GetSyncTimeStamp();

	    // Generate HAE_SOLARIS_FRAMES_PER_BLOCK frames of audio
	    pFillBuffer = (char *)g_audioBufferBlock;	
	    for (count = 0; count < HAE_SOLARIS_FRAMES_PER_BLOCK; count++) {
				// Generate one frame audio
		HAE_BuildMixerSlice(context, pFillBuffer, g_audioByteBufferSize,
				    g_audioFramesToGenerate);

		pFillBuffer += g_audioByteBufferSize;

		if (g_shutDownDoubleBuffer) {
		    break;	// time to quit
		}
	    }

	    // $$kk
	    // for some solaris drivers, we must supply unsigned data when rendering 8 bit data
	    if (g_convertUnsigned && (g_bitSize == 8)) {
		pFillBuffer = (char *)g_audioBufferBlock;	
		for (i = 0; i < (g_audioByteBufferSize * HAE_SOLARIS_FRAMES_PER_BLOCK); i++) {
		    *pFillBuffer = (*pFillBuffer >= 0) ? (0x80 | *pFillBuffer) : (0x7F & *pFillBuffer);
		    pFillBuffer++;
		}
	    }
	
	    // $$jb: Changing the write() loop to handle cases when the 
	    // device is unavailable, or we can't write our entire buffer
	    bytesWritten = 0;
	    bytesToWrite = (g_audioByteBufferSize * HAE_SOLARIS_FRAMES_PER_BLOCK);
	    while( bytesToWrite > 0 )  {
		//$$fb don't write when it's time to quit.
		if( g_shutDownDoubleBuffer) {
		    break;
		}
		rc = write(g_waveDevice, ((char *)g_audioBufferBlock+bytesWritten), (size_t)bytesToWrite);
		if ( rc > 0 ) {
#ifdef USE_RAWDATA_CHECK
		    if (debugrawfile) {
			HAE_WriteFile(debugrawfile, ((char *)g_audioBufferBlock+bytesWritten), rc);
		    }
#endif
		    bytesWritten += rc;
		    bytesToWrite -= rc;
		} else {
                                // $$jb:  This happens when the device buffers cannot
                                // be written to.  Make sure we're not shutting down and 
                                // sleep a bit so that we don't completely hog the CPU
		    if( g_shutDownDoubleBuffer == FALSE ) {
			HAE_SleepFrameThread(context, HAE_SOLARIS_SOUND_PERIOD);
		    } else {
			break;
		    }
		} 
	    }


	    // O.k. We're done for now.
	    // Let the rest of the system know we're done ....

	    ioctl(g_waveDevice, AUDIO_GETINFO, &sunAudioHeader);
	    currentPos = sunAudioHeader.play.samples;

	    // $$jb: We have successfully written all our bytes.  
	    // If we encountered a problem while writing, play.error will be 1.
	    // This should be reset.
	    if( sunAudioHeader.play.error != 0 ) {
		AUDIO_INITINFO(&sunAudioHeader);
		sunAudioHeader.play.error = 0;
		ioctl(g_waveDevice, AUDIO_SETINFO, &sunAudioHeader);
	    }

			
	    // $$kk: 03.21.00: make sure we sleep at least once so that other threads can run.
	    // this is part of the fix for bug #4318062: "MixerSourceLine.drain hangs after
	    // repeated use."
	    //while ((currentPos < lastPos) && (g_shutDownDoubleBuffer == FALSE))
	    do {
		HAE_SleepFrameThread(context, HAE_SOLARIS_SOUND_PERIOD);		// in ms
				
		ioctl(g_waveDevice, AUDIO_GETINFO, &sunAudioHeader);
		currentPos = sunAudioHeader.play.samples;

                                // $$jb: Removing the bit of code that breaks out
                                // of this timing loop on sunAudioHeader.play.error != 0.
	    }
	    while ((currentPos < lastPos) &&
		   (lastPos - currentPos < (1 << 28)) && /* see note A */
		   (g_shutDownDoubleBuffer == FALSE));

	    // Note A: $$ay: Additional safeguard for wraparound of sample
	    // ------  count from 1 << 32 - 1.  Make sure the difference is
	    //         not a huge value
			
	    lastPos += (g_audioByteBufferSize * HAE_SOLARIS_FRAMES_PER_BLOCK) / sampleFrameSize;
	    // ... and reschedule ourselves.	
	}

	g_activeDoubleBuffer = FALSE;
    }
}
Beispiel #29
0
static int
BSDAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
{
    const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT);
    SDL_AudioFormat format = 0;
    audio_info_t info;

    /* We don't care what the devname is...we'll try to open anything. */
    /*  ...but default to first name in the list... */
    if (devname == NULL) {
        devname = SDL_GetAudioDeviceName(0, iscapture);
        if (devname == NULL) {
            SDL_SetError("No such audio device");
            return 0;
        }
    }

    /* Initialize all variables that we clean on shutdown */
    this->hidden = (struct SDL_PrivateAudioData *)
        SDL_malloc((sizeof *this->hidden));
    if (this->hidden == NULL) {
        SDL_OutOfMemory();
        return 0;
    }
    SDL_memset(this->hidden, 0, (sizeof *this->hidden));

    /* Open the audio device */
    this->hidden->audio_fd = open(devname, flags, 0);
    if (this->hidden->audio_fd < 0) {
        SDL_SetError("Couldn't open %s: %s", devname, strerror(errno));
        return 0;
    }

    AUDIO_INITINFO(&info);

    /* Calculate the final parameters for this audio specification */
    SDL_CalculateAudioSpec(&this->spec);

    /* Set to play mode */
    info.mode = AUMODE_PLAY;
    if (ioctl(this->hidden->audio_fd, AUDIO_SETINFO, &info) < 0) {
        BSDAUDIO_CloseDevice(this);
        SDL_SetError("Couldn't put device into play mode");
        return 0;
    }

    AUDIO_INITINFO(&info);
    for (format = SDL_FirstAudioFormat(this->spec.format);
         format; format = SDL_NextAudioFormat()) {
        switch (format) {
        case AUDIO_U8:
            info.play.encoding = AUDIO_ENCODING_ULINEAR;
            info.play.precision = 8;
            break;
        case AUDIO_S8:
            info.play.encoding = AUDIO_ENCODING_SLINEAR;
            info.play.precision = 8;
            break;
        case AUDIO_S16LSB:
            info.play.encoding = AUDIO_ENCODING_SLINEAR_LE;
            info.play.precision = 16;
            break;
        case AUDIO_S16MSB:
            info.play.encoding = AUDIO_ENCODING_SLINEAR_BE;
            info.play.precision = 16;
            break;
        case AUDIO_U16LSB:
            info.play.encoding = AUDIO_ENCODING_ULINEAR_LE;
            info.play.precision = 16;
            break;
        case AUDIO_U16MSB:
            info.play.encoding = AUDIO_ENCODING_ULINEAR_BE;
            info.play.precision = 16;
            break;
        default:
            continue;
        }

        if (ioctl(this->hidden->audio_fd, AUDIO_SETINFO, &info) == 0) {
            break;
        }
    }

    if (!format) {
        BSDAUDIO_CloseDevice(this);
        SDL_SetError("No supported encoding for 0x%x", this->spec.format);
        return 0;
    }

    this->spec.format = format;

    AUDIO_INITINFO(&info);
    info.play.channels = this->spec.channels;
    if (ioctl(this->hidden->audio_fd, AUDIO_SETINFO, &info) == -1) {
        this->spec.channels = 1;
    }
    AUDIO_INITINFO(&info);
    info.play.sample_rate = this->spec.freq;
    info.blocksize = this->spec.size;
    info.hiwat = 5;
    info.lowat = 3;
    (void) ioctl(this->hidden->audio_fd, AUDIO_SETINFO, &info);
    (void) ioctl(this->hidden->audio_fd, AUDIO_GETINFO, &info);
    this->spec.freq = info.play.sample_rate;
    /* Allocate mixing buffer */
    this->hidden->mixlen = this->spec.size;
    this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
    if (this->hidden->mixbuf == NULL) {
        BSDAUDIO_CloseDevice(this);
        SDL_OutOfMemory();
        return 0;
    }
    SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);

    BSDAUDIO_Status(this);

    /* We're ready to rock and roll. :-) */
    return (0);
}
Beispiel #30
0
static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
    struct userdata *u = PA_SINK(o)->userdata;
    int err;
    audio_info_t info;

    switch (code) {
    case PA_SINK_MESSAGE_GET_LATENCY: {
        pa_usec_t r = 0;

        if (u->fd >= 0) {

            err = ioctl(u->fd, AUDIO_GETINFO, &info);
            pa_assert(err >= 0);

            r += pa_bytes_to_usec(u->written_bytes, &PA_SINK(o)->sample_spec);
            r -= pa_bytes_to_usec(info.play.samples * u->frame_size, &PA_SINK(o)->sample_spec);

            if (u->memchunk.memblock)
                r += pa_bytes_to_usec(u->memchunk.length, &PA_SINK(o)->sample_spec);
        }

        *((pa_usec_t*) data) = r;

        return 0;
    }

    case PA_SINK_MESSAGE_SET_VOLUME:
        if (u->fd >= 0) {
            AUDIO_INITINFO(&info);

            info.play.gain = pa_cvolume_avg((pa_cvolume*)data) * AUDIO_MAX_GAIN / PA_VOLUME_NORM;
            assert(info.play.gain <= AUDIO_MAX_GAIN);

            if (ioctl(u->fd, AUDIO_SETINFO, &info) < 0) {
                if (errno == EINVAL)
                    pa_log("AUDIO_SETINFO: Unsupported volume.");
                else
                    pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno));
            } else {
                return 0;
            }
        }
        break;

    case PA_SINK_MESSAGE_GET_VOLUME:
        if (u->fd >= 0) {
            err = ioctl(u->fd, AUDIO_GETINFO, &info);
            assert(err >= 0);

            pa_cvolume_set((pa_cvolume*) data, ((pa_cvolume*) data)->channels,
                info.play.gain * PA_VOLUME_NORM / AUDIO_MAX_GAIN);

            return 0;
        }
        break;

    case PA_SINK_MESSAGE_SET_MUTE:
        if (u->fd >= 0) {
            AUDIO_INITINFO(&info);

            info.output_muted = !!PA_PTR_TO_UINT(data);

            if (ioctl(u->fd, AUDIO_SETINFO, &info) < 0)
                pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno));
            else
                return 0;
        }
        break;

    case PA_SINK_MESSAGE_GET_MUTE:
        if (u->fd >= 0) {
            err = ioctl(u->fd, AUDIO_GETINFO, &info);
            pa_assert(err >= 0);

            *(int*)data = !!info.output_muted;

            return 0;
        }
        break;
    }

    return pa_sink_process_msg(o, code, data, offset, chunk);
}