static snd_pcm_t *open_audiofd( char *device_name, int capture, int rate, int channels, int period, int nperiods ) { int err; snd_pcm_t *handle; snd_pcm_hw_params_t *hwparams; snd_pcm_sw_params_t *swparams; snd_pcm_hw_params_alloca(&hwparams); snd_pcm_sw_params_alloca(&swparams); if ((err = snd_pcm_open(&(handle), device_name, capture ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK )) < 0) { printf("Capture open error: %s\n", snd_strerror(err)); return NULL; } if ((err = set_hwparams(handle, hwparams,SND_PCM_ACCESS_RW_INTERLEAVED, rate, channels, period, nperiods )) < 0) { printf("Setting of hwparams failed: %s\n", snd_strerror(err)); return NULL; } if ((err = set_swparams(handle, swparams, period, nperiods)) < 0) { printf("Setting of swparams failed: %s\n", snd_strerror(err)); return NULL; } //snd_pcm_start( handle ); //snd_pcm_wait( handle, 200 ); int num_null_samples = nperiods * period * channels; char *tmp = alloca( num_null_samples * formats[format].sample_size ); memset( tmp, 0, num_null_samples * formats[format].sample_size ); snd_pcm_writei( handle, tmp, num_null_samples ); return handle; }
int alsa_open( void ) { int err; snd_pcm_hw_params_t *hwparams; snd_pcm_sw_params_t *swparams; DEBUGLOG("alsa_open\n"); snd_pcm_hw_params_alloca(&hwparams); snd_pcm_sw_params_alloca(&swparams); if((err = snd_pcm_open(&handle, device, SND_PCM_STREAM_PLAYBACK, 0/*SND_PCM_NONBLOCK*/)) < 0 ) { ERRORLOG("open failed: %s\n", snd_strerror(err)); return -1; } if((err = set_hwparams(hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) { ERRORLOG("Setting of hwparams failed: %s\n", snd_strerror(err)); return -1; } if((err = set_swparams(swparams)) < 0) { ERRORLOG("Setting of swparams failed: %s\n", snd_strerror(err)); return -1; } return 0; }
/********************************************************************************** * pcm_init() * ***********************************************************************************/ static void pcm_init(void) { int err; snd_pcm_hw_params_t *hwparams; snd_pcm_sw_params_t *swparams; snd_pcm_hw_params_alloca(&hwparams); snd_pcm_sw_params_alloca(&swparams); if ((err = snd_pcm_open(&handle, device, SND_PCM_STREAM_PLAYBACK, 0)) < 0) { printf("Playback open error: %s\n", snd_strerror(err)); } if ((err = set_hwparams(handle, hwparams,SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) { printf("Setting of hwparams failed: %s\n", snd_strerror(err)); exit(EXIT_FAILURE); } if ((err = set_swparams(handle, swparams)) < 0) { printf("Setting of swparams failed: %s\n", snd_strerror(err)); exit(EXIT_FAILURE); } /*分配空间 period的空间,period指向空间首地址*/ period_size_real = period_size * channels * snd_pcm_format_physical_width(format) / 8;//snd_pcm_format_physical_width:return bits needed to store a PCM sample. period = malloc(period_size_real); if (period == NULL) { printf("No enough memory\n"); exit(EXIT_FAILURE); } fprintf(stdout,"pcm_init sucess !\n"); }
BOOL alsa_open_audio(BOOL use_mmap) { snd_pcm_hw_params_t *hwparams; snd_pcm_sw_params_t *swparams; int err; snd_pcm_access_t access = (use_mmap)?(SND_PCM_ACCESS_MMAP_INTERLEAVED) :(SND_PCM_ACCESS_RW_INTERLEAVED); format = (use_mmap)?(format_8):(format_16); if (alsa_audiodev_is_open) return TRUE; snd_pcm_hw_params_alloca(&hwparams); snd_pcm_sw_params_alloca(&swparams); err = snd_output_stdio_attach(&output, stdout, 0); if (err < 0) { printf("Output failed: %s\n", snd_strerror(err)); return 0; } if ((err = snd_pcm_open(&playback_handle, device, SND_PCM_STREAM_PLAYBACK, 0)) < 0) { printf("Playback open error: %s\n", snd_strerror(err)); return 0; } if ((err = set_hwparams(playback_handle, hwparams, access)) < 0) { printf("Setting of hwparams failed: %s\n", snd_strerror(err)); return 0; } if ((err = set_swparams(playback_handle, swparams)) < 0) { printf("Setting of swparams failed: %s\n", snd_strerror(err)); return 0; } snd_pcm_dump(playback_handle, output); samples = malloc((period_size * channels * snd_pcm_format_width(format)) / 8); if (samples == NULL) { printf("No enough memory\n"); exit(EXIT_FAILURE); } areas = calloc(channels, sizeof(snd_pcm_channel_area_t)); if (areas == NULL) { printf("No enough memory\n"); exit(EXIT_FAILURE); } for (chn = 0; chn < channels; chn++) { areas[chn].addr = samples; areas[chn].first = chn * snd_pcm_format_width(format); areas[chn].step = channels * snd_pcm_format_width(format); } alsa_audiodev_is_open = TRUE; //err = snd_pcm_writei(playback_handle, samples, (period_size * channels * snd_pcm_format_width(format)) / 8); return TRUE; }
static gboolean gst_alsasrc_prepare (GstAudioSrc * asrc, GstAudioRingBufferSpec * spec) { GstAlsaSrc *alsa; gint err; alsa = GST_ALSA_SRC (asrc); if (!alsasrc_parse_spec (alsa, spec)) goto spec_parse; CHECK (snd_pcm_nonblock (alsa->handle, 0), non_block); CHECK (set_hwparams (alsa), hw_params_failed); CHECK (set_swparams (alsa), sw_params_failed); CHECK (snd_pcm_prepare (alsa->handle), prepare_failed); alsa->bpf = GST_AUDIO_INFO_BPF (&spec->info); spec->segsize = alsa->period_size * alsa->bpf; spec->segtotal = alsa->buffer_size / alsa->period_size; return TRUE; /* ERRORS */ spec_parse: { GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL), ("Error parsing spec")); return FALSE; } non_block: { GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL), ("Could not set device to blocking: %s", snd_strerror (err))); return FALSE; } hw_params_failed: { GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL), ("Setting of hwparams failed: %s", snd_strerror (err))); return FALSE; } sw_params_failed: { GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL), ("Setting of swparams failed: %s", snd_strerror (err))); return FALSE; } prepare_failed: { GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL), ("Prepare failed: %s", snd_strerror (err))); return FALSE; } }
static gboolean gst_alsasink_prepare (GstAudioSink * asink, GstRingBufferSpec * spec) { GstAlsaSink *alsa; gint err; alsa = GST_ALSA_SINK (asink); if (alsa->iec958) { snd_pcm_close (alsa->handle); alsa->handle = gst_alsa_open_iec958_pcm (GST_OBJECT (alsa), alsa->device); if (G_UNLIKELY (!alsa->handle)) { goto no_iec958; } } if (!alsasink_parse_spec (alsa, spec)) goto spec_parse; CHECK (set_hwparams (alsa), hw_params_failed); CHECK (set_swparams (alsa), sw_params_failed); alsa->bytes_per_sample = spec->bytes_per_sample; spec->segsize = alsa->period_size * spec->bytes_per_sample; spec->segtotal = alsa->buffer_size / alsa->period_size; { snd_output_t *out_buf = NULL; char *msg = NULL; snd_output_buffer_open (&out_buf); snd_pcm_dump_hw_setup (alsa->handle, out_buf); snd_output_buffer_string (out_buf, &msg); GST_DEBUG_OBJECT (alsa, "Hardware setup: \n%s", msg); snd_output_close (out_buf); snd_output_buffer_open (&out_buf); snd_pcm_dump_sw_setup (alsa->handle, out_buf); snd_output_buffer_string (out_buf, &msg); GST_DEBUG_OBJECT (alsa, "Software setup: \n%s", msg); snd_output_close (out_buf); } return TRUE; /* ERRORS */ no_iec958: { GST_ELEMENT_ERROR (alsa, RESOURCE, OPEN_WRITE, (NULL), ("Could not open IEC958 (SPDIF) device for playback")); return FALSE; } spec_parse: { GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL), ("Error parsing spec")); return FALSE; } hw_params_failed: { GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL), ("Setting of hwparams failed: %s", snd_strerror (err))); return FALSE; } sw_params_failed: { GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL), ("Setting of swparams failed: %s", snd_strerror (err))); return FALSE; } }
int alsamm_open_audio(int rate, int blocksize) { int err; char devname[80]; char *cardname; snd_pcm_hw_params_t* hw_params; snd_pcm_sw_params_t* sw_params; /* fragsize is an old concept now use periods, used to be called fragments. */ /* Be aware in ALSA periodsize can be in bytes, where buffersize is in frames, but sometimes buffersize is in bytes and periods in frames, crazy alsa... ...we use periodsize and buffersize in frames */ int i; short* tmp_buf; unsigned int tmp_uint; snd_pcm_hw_params_alloca(&hw_params); snd_pcm_sw_params_alloca(&sw_params); /* see add_devname */ /* first have a look which cards we can get and set up device infos for them */ #ifdef ALSAMM_DEBUG if(sys_verbose) post("naudioindev=%d, nchindev=%d, naudiooutdev=%d, nchoutdev=%d,rate=%d", naudioindev, nchindev,naudiooutdev, nchoutdev, rate); #endif /* init some structures */ for(i=0;i < ALSA_MAXDEV;i++){ alsa_indev[i].a_synced=alsa_outdev[i].a_synced=0; alsa_indev[i].a_channels=alsa_outdev[i].a_channels=-1; /* query defaults */ } alsamm_inchannels = 0; alsamm_outchannels = 0; /* opening alsa debug channel */ err = snd_output_stdio_attach(&alsa_stdout, stdout, 0); if (err < 0) { check_error(err,"attaching alsa debug Output to stdout failed"); /* return; no so bad ... and never should happe */ } /* Weak failure prevention: first card found (out then in) is used as a reference for parameter, so this set the globals and other cards hopefully don't change them */ alsamm_sr = rate; /* set the asked buffer time (alsa buffertime in us)*/ alsamm_buffertime = alsamm_buffersize = 0; if(blocksize == 0) alsamm_buffertime = sys_schedadvance; else alsamm_buffersize = blocksize; if(sys_verbose) post("syschedadvance=%d us(%d Samples)so buffertime max should be this=%d" "or sys_blocksize=%d (samples) to use buffersize=%d", sys_schedadvance,sys_advance_samples,alsamm_buffertime, blocksize,alsamm_buffersize); alsamm_periods = 0; /* no one wants periods setting from command line ;-) */ for(i=0;i<alsa_noutdev;i++) { /* post("open audio out %d, of %lx, %d",i,&alsa_device[i], alsa_outdev[i].a_handle); */ if((err = set_hwparams(alsa_outdev[i].a_handle, hw_params, &(alsa_outdev[i].a_channels))) < 0) { check_error(err,"playback device hwparam_set error:"); continue; } if((err = set_swparams(alsa_outdev[i].a_handle, sw_params,1)) < 0){ check_error(err,"playback device swparam_set error:"); continue; } alsamm_outchannels += alsa_outdev[i].a_channels; alsa_outdev[i].a_addr = (char **) malloc(sizeof(char *) * alsa_outdev[i].a_channels); if(alsa_outdev[i].a_addr == NULL){ check_error(errno,"playback device outaddr allocation error:"); continue; } memset(alsa_outdev[i].a_addr, 0, sizeof(char*) * alsa_outdev[i].a_channels); post("playback device with %d channels and buffer_time %d us opened", alsa_outdev[i].a_channels, alsamm_buffertime); } for(i=0;i<alsa_nindev;i++) { if(sys_verbose) post("capture card %d:--------------------",i); if((err = set_hwparams(alsa_indev[i].a_handle, hw_params, &(alsa_indev[i].a_channels))) < 0) { check_error(err,"capture device hwparam_set error:"); continue; } alsamm_inchannels += alsa_indev[i].a_channels; if((err = set_swparams(alsa_indev[i].a_handle, sw_params,0)) < 0){ check_error(err,"capture device swparam_set error:"); continue; } alsa_indev[i].a_addr = (char **) malloc (sizeof(char*) * alsa_indev[i].a_channels); if(alsa_indev[i].a_addr == NULL){ check_error(errno,"capture device inaddr allocation error:"); continue; } memset(alsa_indev[i].a_addr, 0, sizeof(char*) * alsa_indev[i].a_channels); if(sys_verbose) post("capture device with %d channels and buffertime %d us opened\n", alsa_indev[i].a_channels,alsamm_buffertime); } /* check for linked handles of input for each output*/ for(i=0; i<(alsa_noutdev < alsa_nindev ? alsa_noutdev:alsa_nindev); i++){ t_alsa_dev *ad = &alsa_outdev[i]; if (alsa_outdev[i].a_devno == alsa_indev[i].a_devno){ if ((err = snd_pcm_link (alsa_indev[i].a_handle, alsa_outdev[i].a_handle)) == 0){ alsa_indev[i].a_synced = alsa_outdev[i].a_synced = 1; if(sys_verbose) post("Linking in and outs of card %d",i); } else check_error(err,"could not link in and outs"); } } /* some globals */ sleep_time = (float) alsamm_period_size/ (float) alsamm_sr; #ifdef ALSAMM_DEBUG /* start ---------------------------- */ if(sys_verbose) post("open_audio: after dacsend=%d (xruns=%d)done",dac_send,alsamm_xruns); alsamm_xruns = dac_send = 0; /* reset debug */ /* start alsa in open or better in send_dacs once ??? we will see */ for(i=0;i<alsa_noutdev;i++) snd_pcm_dump(alsa_outdev[i].a_handle, alsa_stdout); for(i=0;i<alsa_nindev;i++) snd_pcm_dump(alsa_indev[i].inhandle, alsa_stdout); fflush(stdout); #endif sys_setchsr(alsamm_inchannels, alsamm_outchannels, alsamm_sr); alsamm_start(); /* report success */ return (0); }
static gboolean gst_alsasrc_prepare (GstAudioSrc * asrc, GstAudioRingBufferSpec * spec) { GstAlsaSrc *alsa; gint err; alsa = GST_ALSA_SRC (asrc); if (!alsasrc_parse_spec (alsa, spec)) goto spec_parse; CHECK (snd_pcm_nonblock (alsa->handle, 0), non_block); CHECK (set_hwparams (alsa), hw_params_failed); CHECK (set_swparams (alsa), sw_params_failed); CHECK (snd_pcm_prepare (alsa->handle), prepare_failed); alsa->bpf = GST_AUDIO_INFO_BPF (&spec->info); spec->segsize = alsa->period_size * alsa->bpf; spec->segtotal = alsa->buffer_size / alsa->period_size; { snd_output_t *out_buf = NULL; char *msg = NULL; snd_output_buffer_open (&out_buf); snd_pcm_dump_hw_setup (alsa->handle, out_buf); snd_output_buffer_string (out_buf, &msg); GST_DEBUG_OBJECT (alsa, "Hardware setup: \n%s", msg); snd_output_close (out_buf); snd_output_buffer_open (&out_buf); snd_pcm_dump_sw_setup (alsa->handle, out_buf); snd_output_buffer_string (out_buf, &msg); GST_DEBUG_OBJECT (alsa, "Software setup: \n%s", msg); snd_output_close (out_buf); } #ifdef SND_CHMAP_API_VERSION if (spec->type == GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW && alsa->channels < 9) { snd_pcm_chmap_t *chmap = snd_pcm_get_chmap (alsa->handle); if (chmap && chmap->channels == alsa->channels) { GstAudioChannelPosition pos[8]; if (alsa_chmap_to_channel_positions (chmap, pos)) gst_audio_ring_buffer_set_channel_positions (GST_AUDIO_BASE_SRC (alsa)->ringbuffer, pos); } free (chmap); } #endif /* SND_CHMAP_API_VERSION */ return TRUE; /* ERRORS */ spec_parse: { GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL), ("Error parsing spec")); return FALSE; } non_block: { GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL), ("Could not set device to blocking: %s", snd_strerror (err))); return FALSE; } hw_params_failed: { GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL), ("Setting of hwparams failed: %s", snd_strerror (err))); return FALSE; } sw_params_failed: { GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL), ("Setting of swparams failed: %s", snd_strerror (err))); return FALSE; } prepare_failed: { GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL), ("Prepare failed: %s", snd_strerror (err))); return FALSE; } }
static BOOL ALSA_Init_internal(void) { snd_pcm_format_t pformat; #ifdef OLD_ALSA #define channels pformat.channels #define rate pformat.rate int mask,card; #else int rate; int channels; int err; snd_pcm_hw_params_t * hwparams; snd_pcm_sw_params_t * swparams; #endif /* adjust user-configurable settings */ if((getenv("MM_NUMFRAGS"))&&(numfrags==DEFAULT_NUMFRAGS)) { numfrags=atoi(getenv("MM_NUMFRAGS")); if ((numfrags<2)||(numfrags>16)) numfrags=DEFAULT_NUMFRAGS; } #ifdef OLD_ALSA if((getenv("ALSA_CARD"))&&(!cardmin)&&(cardmax==SND_CARDS)) { cardmin=atoi(getenv("ALSA_CARD")); cardmax=cardmin+1; #endif if(getenv("ALSA_PCM")) device=atoi(getenv("ALSA_PCM")); #ifdef OLD_ALSA } #endif /* setup playback format structure */ #define NUM_CHANNELS() ((md_mode&DMODE_STEREO)?2:1) #ifdef OLD_ALSA memset(&pformat,0,sizeof(pformat)); #ifdef SND_LITTLE_ENDIAN pformat.format=(md_mode&DMODE_16BITS)?SND_PCM_SFMT_S16_LE:SND_PCM_SFMT_U8; #else pformat.format=(md_mode&DMODE_16BITS)?SND_PCM_SFMT_S16_BE:SND_PCM_SFMT_U8; #endif #else pformat = (md_mode&DMODE_16BITS)?SND_PCM_FORMAT_S16_LE:SND_PCM_FORMAT_U8; snd_pcm_hw_params_alloca(&hwparams); snd_pcm_sw_params_alloca(&swparams); #endif channels = NUM_CHANNELS(); rate=md_mixfreq; /* scan for appropriate sound card */ #ifdef OLD_ALSA mask=alsa_cards_mask(); #endif _mm_errno=MMERR_OPENING_AUDIO; #ifdef OLD_ALSA for (card=cardmin;card<cardmax;card++) #endif { #ifdef OLD_ALSA struct snd_ctl_hw_info info; snd_ctl_t *ctl_h; int dev,devmin,devmax; #endif #ifdef OLD_ALSA /* no card here, onto the next */ if (!(mask&(1<<card))) continue; #endif #ifdef OLD_ALSA /* try to open the card in query mode */ if (alsa_ctl_open(&ctl_h,card)<0) continue; #else if ((err = alsa_pcm_open(&pcm_h, "plughw:0,0", SND_PCM_STREAM_PLAYBACK, 0)) < 0) { printf("snd_pcm_open() call failed: %s\n", alsa_strerror(err)); goto END; } #endif #ifdef OLD_ALSA /* get hardware information */ if(alsa_ctl_hw_info(ctl_h,&info)<0) { alsa_ctl_close(ctl_h); continue; } /* scan subdevices */ if(device==-1) { devmin=0;devmax=info.pcmdevs; } else devmin=devmax=device; #endif #ifdef OLD_ALSA for(dev=devmin;dev<devmax;dev++) #endif { #ifdef OLD_ALSA int size,bps; snd_pcm_info_t pcminfo; snd_pcm_playback_info_t ctlinfo; struct snd_pcm_playback_info pinfo; struct snd_pcm_playback_params pparams; /* get PCM capabilities */ if(alsa_ctl_pcm_info(ctl_h,dev,&pcminfo)<0) continue; /* look for playback capability */ if(!(pcminfo.flags&SND_PCM_INFO_PLAYBACK)) continue; /* get playback information */ #if defined(SND_LIB_VERSION) && (SND_LIB_VERSION >= 0x400) if(alsa_ctl_pcm_playback_info(ctl_h,dev,0,&ctlinfo)<0) continue; #else if(alsa_ctl_pcm_playback_info(ctl_h,dev,&ctlinfo)<0) continue; #endif /* If control goes here, we have found a sound device able to play PCM data. Let's open in in playback mode and see if we have compatible playback settings. */ if (alsa_pcm_open(&pcm_h,card,dev,SND_PCM_OPEN_PLAYBACK)<0) continue; if (alsa_pcm_playback_info(pcm_h,&pinfo)<0) { alsa_pcm_close(pcm_h); pcm_h=NULL; continue; } /* check we have compatible settings */ if((pinfo.min_rate>rate)||(pinfo.max_rate<rate)|| (!(pinfo.formats&(1<<pformat.format)))) { alsa_pcm_close(pcm_h); pcm_h=NULL; continue; } fragmentsize=pinfo.buffer_size/numfrags; #ifdef MIKMOD_DEBUG if ((fragmentsize<512)||(fragmentsize>16777216L)) fprintf(stderr,"\rweird pinfo.buffer_size:%d\n",pinfo.buffer_size); #endif alsa_pcm_flush_playback(pcm_h); /* set new parameters */ if(alsa_pcm_playback_format(pcm_h,&pformat)<0) #else if( alsa_pcm_set_params(pcm_h, pformat, SND_PCM_ACCESS_RW_INTERLEAVED, channels, rate, 1, 500000 /* 0.5sec */ ) < 0) #endif { alsa_pcm_close(pcm_h); pcm_h=NULL; #ifdef OLD_ALSA continue; #else goto END; #endif } global_frame_size = channels*(md_mode&DMODE_16BITS?2:1); #ifdef OLD_ALSA /* compute a fragmentsize hint each fragment should be shorter than, but close to, half a second of playback */ bps=(rate*global_frame_size)>>1; size=fragmentsize;while (size>bps) size>>=1; #endif #ifdef MIKMOD_DEBUG if (size < 16) { fprintf(stderr,"\rweird hint result:%d from %d, bps=%d\n",size,fragmentsize,bps); size=16; } #endif #ifdef OLD_ALSA buffer_size = size; memset(&pparams,0,sizeof(pparams)); pparams.fragment_size=size; pparams.fragments_max=-1; /* choose the best */ pparams.fragments_room=-1; if(alsa_pcm_playback_params(pcm_h,&pparams)<0) { alsa_pcm_close(pcm_h); pcm_h=NULL; continue; } #else /* choose all parameters */ err = alsa_pcm_hw_params_any(pcm_h, hwparams); if (err < 0) { printf("Broken configuration for playback: no configurations available: %s\n", snd_strerror(err)); goto END; } { snd_pcm_uframes_t temp_u_buffer_size, temp_u_period_size; err = alsa_pcm_get_params(pcm_h, &temp_u_buffer_size, &temp_u_period_size); if (err < 0) { alsa_pcm_close(pcm_h); pcm_h=NULL; printf("Unable to get buffer size for playback: %s\n", alsa_strerror(err)); goto END; } buffer_size_in_frames = 1200; period_size = temp_u_period_size; } /* The set_swparams function was taken from test/pcm.c * in the alsa-lib distribution*/ if ((err = set_swparams(pcm_h, swparams)) < 0) { printf("Setting of swparams failed: %s\n", snd_strerror(err)); goto END; } #endif if (!(audiobuffer=(SBYTE*)MikMod_malloc( #ifdef OLD_ALSA fragmentsize #else buffer_size_in_frames * global_frame_size #endif ))) { #ifdef OLD_ALSA alsa_ctl_close(ctl_h); #else alsa_pcm_close(pcm_h); #endif return 1; } /* sound device is ready to work */ if (VC_Init()) { #ifdef OLD_ALSA alsa_ctl_close(ctl_h); #else alsa_pcm_close(pcm_h); #endif return 1; } else return 0; } #ifdef OLD_ALSA alsa_ctl_close(ctl_h); #else alsa_pcm_close(pcm_h); #endif } END: return 1; }
static int config(struct audio_config *config) { int err; snd_pcm_hw_params_alloca(&alsa_hwparams); snd_pcm_sw_params_alloca(&alsa_swparams); bitdepth = config->precision; channels = config->channels; rate = config->speed; if ( bitdepth == 0 ) config->precision = bitdepth = 32; switch (bitdepth) { case 8: alsa_format = SND_PCM_FORMAT_U8; audio_pcm = audio_pcm_u8; break; case 16: alsa_format = SND_PCM_FORMAT_S16; #if __BYTE_ORDER == __LITTLE_ENDIAN audio_pcm = audio_pcm_s16le; #else audio_pcm = audio_pcm_s16be; #endif break; case 24: config->precision = bitdepth = 32; case 32: alsa_format = SND_PCM_FORMAT_S32; #if __BYTE_ORDER == __LITTLE_ENDIAN audio_pcm = audio_pcm_s32le; #else audio_pcm = audio_pcm_s32be; #endif break; default: audio_error="bitdepth not one of [8,16,24,32]"; return -1; } sample_size = bitdepth * channels / 8; err = set_hwparams(alsa_handle, alsa_hwparams, SND_PCM_ACCESS_MMAP_NONINTERLEAVED); if (err < 0) { audio_error=snd_strerror(err); return -1; } err = set_swparams(alsa_handle, alsa_swparams); if (err < 0) { audio_error=snd_strerror(err); return -1; } err = snd_pcm_prepare(alsa_handle); if (err < 0) { audio_error=snd_strerror(err); return -1; } buf = malloc(buffer_size); if (buf == NULL) { audio_error="unable to allocate output buffer table"; return -1; } return 0; }
static gboolean gst_alsasrc_prepare (GstAudioSrc * asrc, GstAudioRingBufferSpec * spec) { GstAlsaSrc *alsa; gint err; alsa = GST_ALSA_SRC (asrc); if (!alsasrc_parse_spec (alsa, spec)) goto spec_parse; CHECK (snd_pcm_nonblock (alsa->handle, 0), non_block); CHECK (set_hwparams (alsa), hw_params_failed); CHECK (set_swparams (alsa), sw_params_failed); CHECK (snd_pcm_prepare (alsa->handle), prepare_failed); alsa->bpf = GST_AUDIO_INFO_BPF (&spec->info); spec->segsize = alsa->period_size * alsa->bpf; spec->segtotal = alsa->buffer_size / alsa->period_size; { snd_output_t *out_buf = NULL; char *msg = NULL; snd_output_buffer_open (&out_buf); snd_pcm_dump_hw_setup (alsa->handle, out_buf); snd_output_buffer_string (out_buf, &msg); GST_DEBUG_OBJECT (alsa, "Hardware setup: \n%s", msg); snd_output_close (out_buf); snd_output_buffer_open (&out_buf); snd_pcm_dump_sw_setup (alsa->handle, out_buf); snd_output_buffer_string (out_buf, &msg); GST_DEBUG_OBJECT (alsa, "Software setup: \n%s", msg); snd_output_close (out_buf); } #ifdef SND_CHMAP_API_VERSION alsa_detect_channels_mapping (GST_OBJECT (alsa), alsa->handle, spec, alsa->channels, GST_AUDIO_BASE_SRC (alsa)->ringbuffer); #endif /* SND_CHMAP_API_VERSION */ return TRUE; /* ERRORS */ spec_parse: { GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL), ("Error parsing spec")); return FALSE; } non_block: { GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL), ("Could not set device to blocking: %s", snd_strerror (err))); return FALSE; } hw_params_failed: { GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL), ("Setting of hwparams failed: %s", snd_strerror (err))); return FALSE; } sw_params_failed: { GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL), ("Setting of swparams failed: %s", snd_strerror (err))); return FALSE; } prepare_failed: { GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL), ("Prepare failed: %s", snd_strerror (err))); return FALSE; } }
static gboolean gst_alsasink_prepare (GstAudioSink * asink, GstAudioRingBufferSpec * spec) { GstAlsaSink *alsa; gint err; alsa = GST_ALSA_SINK (asink); if (alsa->iec958) { snd_pcm_close (alsa->handle); alsa->handle = gst_alsa_open_iec958_pcm (GST_OBJECT (alsa), alsa->device); if (G_UNLIKELY (!alsa->handle)) { goto no_iec958; } } if (!alsasink_parse_spec (alsa, spec)) goto spec_parse; CHECK (set_hwparams (alsa), hw_params_failed); CHECK (set_swparams (alsa), sw_params_failed); alsa->bpf = GST_AUDIO_INFO_BPF (&spec->info); spec->segsize = alsa->period_size * alsa->bpf; spec->segtotal = alsa->buffer_size / alsa->period_size; { snd_output_t *out_buf = NULL; char *msg = NULL; snd_output_buffer_open (&out_buf); snd_pcm_dump_hw_setup (alsa->handle, out_buf); snd_output_buffer_string (out_buf, &msg); GST_DEBUG_OBJECT (alsa, "Hardware setup: \n%s", msg); snd_output_close (out_buf); snd_output_buffer_open (&out_buf); snd_pcm_dump_sw_setup (alsa->handle, out_buf); snd_output_buffer_string (out_buf, &msg); GST_DEBUG_OBJECT (alsa, "Software setup: \n%s", msg); snd_output_close (out_buf); } #ifdef SND_CHMAP_API_VERSION if (spec->type == GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW && alsa->channels < 9) { snd_pcm_chmap_t *chmap = snd_pcm_get_chmap (alsa->handle); if (chmap && chmap->channels == alsa->channels) { GstAudioChannelPosition pos[8]; if (alsa_chmap_to_channel_positions (chmap, pos)) gst_audio_ring_buffer_set_channel_positions (GST_AUDIO_BASE_SINK (alsa)->ringbuffer, pos); } free (chmap); } #endif /* SND_CHMAP_API_VERSION */ return TRUE; /* ERRORS */ no_iec958: { GST_ELEMENT_ERROR (alsa, RESOURCE, OPEN_WRITE, (NULL), ("Could not open IEC958 (SPDIF) device for playback")); return FALSE; } spec_parse: { GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL), ("Error parsing spec")); return FALSE; } hw_params_failed: { GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL), ("Setting of hwparams failed: %s", snd_strerror (err))); return FALSE; } sw_params_failed: { GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL), ("Setting of swparams failed: %s", snd_strerror (err))); return FALSE; } }