int set_pcm() { int rc; int dir = 0; int rate = 44100;; /* ???? 44.1KHz*/ int format = SND_PCM_FORMAT_S16_LE; /* ???? 16 */ int channels = 2; /* ??? 2 */ rc = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0); if (rc < 0) { perror("\nopen PCM device failed:"); exit(1); } snd_pcm_hw_params_alloca(¶ms); //??params??? rc = snd_pcm_hw_params_any(handle, params); //???params if (rc < 0) { perror("\nsnd_pcm_hw_params_any:"); exit(1); } rc = snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); //??????? if (rc < 0) { perror("\nsed_pcm_hw_set_access:"); exit(1); } rc = snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE); //??16????? if (rc < 0) { perror("snd_pcm_hw_params_set_format failed:"); exit(1); } rc = snd_pcm_hw_params_set_channels(handle, params, channels); //????,1????>??2????? if (rc < 0) { perror("\nsnd_pcm_hw_params_set_channels:"); exit(1); } rc = snd_pcm_hw_params_set_rate_near(handle, params, &rate, &dir); //??>?? if (rc < 0) { perror("\nsnd_pcm_hw_params_set_rate_near:"); exit(1); } rc = snd_pcm_hw_params(handle, params); if (rc < 0) { perror("\nsnd_pcm_hw_params: "); exit(1); } return 0; }
/* return 0 on success */ int alsa_open_audio(int naudioindev, int *audioindev, int nchindev, int *chindev, int naudiooutdev, int *audiooutdev, int nchoutdev, int *choutdev, int rate, int blocksize) { int err, inchans = 0, outchans = 0, subunitdir; char devname[512]; snd_output_t* out; int frag_size = (blocksize ? blocksize : ALSA_DEFFRAGSIZE); int nfrags, i, iodev, dev2; int wantinchans, wantoutchans, device; nfrags = sys_schedadvance * (float)rate / (1e6 * frag_size); /* save our belief as to ALSA's buffer size for later */ alsa_buf_samps = nfrags * frag_size; alsa_nindev = alsa_noutdev = 0; alsa_jittermax = ALSA_DEFJITTERMAX; if (sys_verbose) post("audio buffer set to %d", (int)(0.001 * sys_schedadvance)); for (iodev = 0; iodev < naudioindev; iodev++) { alsa_numbertoname(audioindev[iodev], devname, 512); err = snd_pcm_open(&alsa_indev[alsa_nindev].a_handle, devname, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK); check_error(err, 0, "snd_pcm_open"); if (err < 0) continue; alsa_indev[alsa_nindev].a_devno = audioindev[iodev]; snd_pcm_nonblock(alsa_indev[alsa_nindev].a_handle, 1); if (sys_verbose) post("opened input device name %s", devname); alsa_nindev++; } for (iodev = 0; iodev < naudiooutdev; iodev++) { alsa_numbertoname(audiooutdev[iodev], devname, 512); err = snd_pcm_open(&alsa_outdev[alsa_noutdev].a_handle, devname, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); check_error(err, 1, "snd_pcm_open"); if (err < 0) continue; alsa_outdev[alsa_noutdev].a_devno = audiooutdev[iodev]; snd_pcm_nonblock(alsa_outdev[alsa_noutdev].a_handle, 1); alsa_noutdev++; } if (!alsa_nindev && !alsa_noutdev) goto blewit; /* If all the open devices support mmap_noninterleaved, let's call Wini's code in s_audio_alsamm.c */ alsa_usemmap = 1; for (iodev = 0; iodev < alsa_nindev; iodev++) if (!alsaio_canmmap(&alsa_indev[iodev])) alsa_usemmap = 0; for (iodev = 0; iodev < alsa_noutdev; iodev++) if (!alsaio_canmmap(&alsa_outdev[iodev])) alsa_usemmap = 0; if (alsa_usemmap) { post("using mmap audio interface"); if (alsamm_open_audio(rate, blocksize)) goto blewit; else return (0); } for (iodev = 0; iodev < alsa_nindev; iodev++) { int channels = chindev[iodev]; if (alsaio_setup(&alsa_indev[iodev], 0, &channels, &rate, nfrags, frag_size) < 0) goto blewit; inchans += channels; } for (iodev = 0; iodev < alsa_noutdev; iodev++) { int channels = choutdev[iodev]; if (alsaio_setup(&alsa_outdev[iodev], 1, &channels, &rate, nfrags, frag_size) < 0) goto blewit; outchans += channels; } if (!inchans && !outchans) goto blewit; for (iodev = 0; iodev < alsa_nindev; iodev++) snd_pcm_prepare(alsa_indev[iodev].a_handle); for (iodev = 0; iodev < alsa_noutdev; iodev++) snd_pcm_prepare(alsa_outdev[iodev].a_handle); /* if duplex we can link the channels so they start together */ for (iodev = 0; iodev < alsa_nindev; iodev++) for (dev2 = 0; dev2 < alsa_noutdev; dev2++) { if (alsa_indev[iodev].a_devno == alsa_outdev[iodev].a_devno) { snd_pcm_link(alsa_indev[iodev].a_handle, alsa_outdev[iodev].a_handle); } } /* allocate the status variables */ if (!alsa_status) { err = snd_pcm_status_malloc(&alsa_status); check_error(err, -1, "snd_pcm_status_malloc"); } /* fill the buffer with silence and prime the output FIFOs. This should automatically start the output devices. */ memset(alsa_snd_buf, 0, alsa_snd_bufsize); if (outchans) { i = (frag_size * nfrags)/DEFDACBLKSIZE + 1; while (i--) { for (iodev = 0; iodev < alsa_noutdev; iodev++) snd_pcm_writei(alsa_outdev[iodev].a_handle, alsa_snd_buf, DEFDACBLKSIZE); } } if (inchans) { /* some of the ADC devices might already have been started by starting the outputs above, but others might still need it. */ for (iodev = 0; iodev < alsa_nindev; iodev++) if (snd_pcm_state(alsa_indev[iodev].a_handle) != SND_PCM_STATE_RUNNING) if ((err = snd_pcm_start(alsa_indev[iodev].a_handle)) < 0) check_error(err, -1, "input start failed"); } return (0); blewit: STUFF->st_inchannels = 0; STUFF->st_outchannels = 0; alsa_close_audio(); return (1); }
static int alsa_audio_reconfig(audio_decoder_t *ad) { decoder_t *d = (decoder_t *)ad; snd_pcm_t *h; int r; alsa_audio_fini(ad); if(d->h != NULL) { snd_pcm_close(d->h); d->h = NULL; TRACE(TRACE_DEBUG, "ALSA", "Closing device"); } const char *dev = alsa_get_devicename(); if((r = snd_pcm_open(&h, dev, SND_PCM_STREAM_PLAYBACK, 0) < 0)) { TRACE(TRACE_ERROR, "ALSA", "Unable to open %s -- %s", dev, snd_strerror(r)); return -1; } r = snd_pcm_set_params(h, SND_PCM_FORMAT_S16, SND_PCM_ACCESS_RW_INTERLEAVED, 2, 48000, 0, 100000); if(r < 0) { TRACE(TRACE_ERROR, "ALSA", "Unable to set params on %s -- %s", dev, snd_strerror(r)); return -1; } snd_pcm_hw_params_t *hwp; snd_pcm_hw_params_alloca(&hwp); snd_pcm_hw_params_current(h, hwp); unsigned int val; snd_pcm_uframes_t psize, bsize; snd_pcm_hw_params_get_rate(hwp, &val, 0); ad->ad_out_sample_rate = val; snd_pcm_hw_params_get_period_size(hwp, &psize, 0); ad->ad_tile_size = psize * 2; snd_pcm_hw_params_get_buffer_size(hwp, &bsize); d->max_frames_per_write = bsize; TRACE(TRACE_DEBUG, "ALSA", "Opened %s", dev); ad->ad_out_sample_format = AV_SAMPLE_FMT_S16; ad->ad_out_sample_rate = 48000; ad->ad_out_channel_layout = AV_CH_LAYOUT_STEREO; d->h = h; snd_pcm_prepare(d->h); int channels = 2; d->tmp = malloc(sizeof(uint16_t) * channels * d->max_frames_per_write); return 0; }
void playback() { int err; unsigned int i; snd_pcm_t *handle; // for (i = 0; i < sizeof(buffer); i++) // buffer[i] = random() & 0xff; if ((err = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0)) < 0) { printf("Playback open error: %s\n", snd_strerror(err)); exit(EXIT_FAILURE); } initialize(handle); printBuffer(buffer, 0, 10); // for (i = 0; i < sizeof(buffer); i++) // buffer[i] = random() & 0xff; for (i = 0; i < NUM_FRAMES; i++) { if ((err = snd_pcm_writei (handle, buffer+FRAME_SIZE*i*mult, FRAME_SIZE)) != FRAME_SIZE) { fprintf (stderr, "write from audio interface failed (%s)\n", err, snd_strerror (err)); exit (1); } fprintf(stdout, "write %d done\n", i); printBuffer(buffer, FRAME_SIZE*i*mult, 10); } snd_pcm_close(handle); // int err; // unsigned int i; // snd_pcm_t *handle; // snd_pcm_sframes_t frames; // for (i = 0; i < sizeof(buffer); i++) // buffer[i] = random() & 0xff; // if ((err = snd_pcm_open(&handle, device, SND_PCM_STREAM_PLAYBACK, 0)) < 0) { // printf("Playback open error: %s\n", snd_strerror(err)); // exit(EXIT_FAILURE); // } // if ((err = snd_pcm_set_params(handle, // SND_PCM_FORMAT_U8, // SND_PCM_ACCESS_RW_INTERLEAVED, // 1, // 48000, // 1, // 500000)) < 0) { /* 0.5sec */ // printf("Playback open error: %s\n", snd_strerror(err)); // exit(EXIT_FAILURE); // } // for (i = 0; i < 16; i++) { // frames = snd_pcm_writei(handle, buffer, sizeof(buffer)); // if (frames < 0) // frames = snd_pcm_recover(handle, frames, 0); // if (frames < 0) { // printf("snd_pcm_writei failed: %s\n", snd_strerror(frames)); // break; // } // if (frames > 0 && frames < (long)sizeof(buffer)) // printf("Short write (expected %li, wrote %li)\n", (long)sizeof(buffer), frames); // } // snd_pcm_close(handle); }
int alsa_play_hw(alsa_play_t alsa_play, glc_audio_format_message_t *fmt_msg) { snd_pcm_hw_params_t *hw_params = NULL; snd_pcm_access_t access; unsigned int period_time; unsigned int buffer_time; int dir = 0, ret = 0; if (unlikely(fmt_msg->id != alsa_play->id)) return 0; alsa_play->flags = fmt_msg->flags; alsa_play->format = fmt_msg->format; alsa_play->rate = fmt_msg->rate; alsa_play->channels = fmt_msg->channels; if (alsa_play->pcm) /* re-open */ snd_pcm_close(alsa_play->pcm); if (alsa_play->flags & GLC_AUDIO_INTERLEAVED) access = SND_PCM_ACCESS_RW_INTERLEAVED; else access = SND_PCM_ACCESS_RW_NONINTERLEAVED; if (unlikely((ret = snd_pcm_open(&alsa_play->pcm, alsa_play->device, SND_PCM_STREAM_PLAYBACK, 0)) < 0)) goto err; snd_pcm_hw_params_alloca(&hw_params); if (unlikely((ret = snd_pcm_hw_params_any(alsa_play->pcm, hw_params)) < 0)) goto err; if (unlikely((ret = snd_pcm_hw_params_set_access(alsa_play->pcm, hw_params, access)) < 0)) goto err; if (unlikely((ret = snd_pcm_hw_params_set_format(alsa_play->pcm, hw_params, glc_fmt_to_pcm_fmt(alsa_play->format))) < 0)) goto err; if (unlikely((ret = snd_pcm_hw_params_set_channels(alsa_play->pcm, hw_params, alsa_play->channels)) < 0)) goto err; if (unlikely((ret = snd_pcm_hw_params_set_rate(alsa_play->pcm, hw_params, alsa_play->rate, 0)) < 0)) goto err; if (unlikely((ret = snd_pcm_hw_params_get_buffer_time_max(hw_params, &buffer_time, 0)))) goto err; if (buffer_time > 1000000) { glc_log(alsa_play->glc, GLC_INFO, "alsa_play", "buffer time max is %u usec. We will limit it to 1 sec", buffer_time); buffer_time = 1000000; } period_time = buffer_time / 4; alsa_play->silence_threshold = period_time*2000; if (unlikely((ret = snd_pcm_hw_params_set_period_time_near(alsa_play->pcm, hw_params, &period_time, 0)) < 0)) goto err; if (unlikely((ret = snd_pcm_hw_params_set_buffer_time_near(alsa_play->pcm, hw_params, &buffer_time, 0)) < 0)) goto err; if (unlikely((ret = snd_pcm_hw_params(alsa_play->pcm, hw_params)) < 0)) goto err; alsa_play->bufs = (void **) malloc(sizeof(void *) * alsa_play->channels); glc_log(alsa_play->glc, GLC_INFO, "alsa_play", "opened pcm %s for playback. buffer_time: %u", alsa_play->device, buffer_time); return 0; err: glc_log(alsa_play->glc, GLC_ERROR, "alsa_play", "can't initialize pcm %s: %s (%d)", alsa_play->device, snd_strerror(ret), ret); return -ret; }
/** * @brief Setup the ALSA handle to the audio device */ void AlsaPlayback::setupHandle() { if(alsa_handle) { snd_pcm_close(alsa_handle); alsa_handle = NULL; } if(snd_pcm_open(&alsa_handle, "default", SND_PCM_STREAM_PLAYBACK, 0) < 0) { TRACE("Unable to open playback device!!\n"); alsa_handle = NULL; } else { int rc = -1; snd_pcm_hw_params_t *params = NULL; /* Allocate a hardware parameters object. */ snd_pcm_hw_params_malloc(¶ms); if(NULL != params) { int dir = 0; /* Fill it in with default values. */ snd_pcm_hw_params_any(alsa_handle, params); /* Set the desired hardware parameters. */ /* Interleaved mode */ snd_pcm_hw_params_set_access(alsa_handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); /* Signed 16-bit little-endian format */ snd_pcm_hw_params_set_format(alsa_handle, params, SND_PCM_FORMAT_S16_LE); /* One channel (mono) */ snd_pcm_hw_params_set_channels(alsa_handle, params, 1); /* set sampling rate */ snd_pcm_hw_params_set_rate_near(alsa_handle, params, &AlsaPlayback::_sample_rate, &dir); /* Set period size to 128 frames (samples) */ frames = AlsaPlayback::FRAME_PERIOD; snd_pcm_hw_params_set_period_size_near(alsa_handle, params, &frames, &dir); snd_pcm_uframes_t buf_size = MINIMUM_SAMPLE_SET_SIZE; snd_pcm_hw_params_set_buffer_size_near(alsa_handle, params, &buf_size); /* Write the parameters to the driver */ rc = snd_pcm_hw_params(alsa_handle, params); if(rc >= 0) { TRACE("AlsaPlayback init completed successfully..\n"); } else { snd_pcm_close(alsa_handle); alsa_handle = NULL; TRACE("AlsaPlayback init failed\n"); } snd_pcm_hw_params_free(params); params = NULL; } else { TRACE("playAudio - snd_pcm_hw_params_alloc() failed\n"); } } }
int init_alsa(unsigned int channels, unsigned sample_rate, snd_pcm_format_t format) { int ret; snd_pcm_hw_params_t *hw_params; playback_handle = NULL; ret = snd_pcm_open(&playback_handle, "default", SND_PCM_STREAM_PLAYBACK, 0); if (ret < 0) { fprintf(stderr, "can NOT open soundcard\n"); goto fail; } ret = snd_pcm_hw_params_malloc(&hw_params); if (ret < 0) { fprintf(stderr, "can NOT allocate hardware paramter structure (%s)\n", snd_strerror(ret)); goto fail; } ret = snd_pcm_hw_params_any(playback_handle, hw_params); if (ret < 0) { fprintf(stderr, "can NOT initialize hardware paramter structure (%s)\n", snd_strerror(ret)); goto fail; } ret = snd_pcm_hw_params_set_access(playback_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED); if (ret < 0) { fprintf(stderr, "can NOT set access type (%s)\n", snd_strerror(ret)); goto fail; } ret = snd_pcm_hw_params_set_format(playback_handle, hw_params, format); if (ret < 0) { fprintf(stderr, "can NOT set sample format (%s)\n", snd_strerror(ret)); goto fail; } ret = snd_pcm_hw_params_set_rate_near(playback_handle, hw_params, &sample_rate, 0); if (ret < 0) { fprintf(stderr, "can NOT set sample rate (%s)\n", snd_strerror(ret)); goto fail; } ret = snd_pcm_hw_params_set_channels(playback_handle, hw_params, channels); if (ret < 0) { fprintf(stderr, "can NOT set channels (%s)\n", snd_strerror(ret)); goto fail; } snd_pcm_hw_params_get_buffer_size_max(hw_params, &buffer_size); buffer_size = buffer_size < ALSA_BUFFER_SIZE_MAX ? buffer_size : ALSA_BUFFER_SIZE_MAX; ret = snd_pcm_hw_params_set_buffer_size_near(playback_handle, hw_params, &buffer_size); if (ret < 0) { fprintf(stderr, "can NOT set alsa buffer size (%s)\n", snd_strerror(ret)); goto fail; } snd_pcm_hw_params_get_period_size_min(hw_params, &period_size, NULL); if (!period_size) period_size = buffer_size / 4; ret = snd_pcm_hw_params_set_period_size_near(playback_handle, hw_params, &period_size, NULL); if (ret < 0) { fprintf(stderr, "can NOT set alsa period size (%s)\n", snd_strerror(ret)); goto fail; } ret = snd_pcm_hw_params(playback_handle, hw_params); if (ret < 0) { fprintf(stderr, "can NOT set parameters (%s)\n", snd_strerror(ret)); goto fail; } snd_pcm_hw_params_free(hw_params); audio_channels = channels; audio_sample_rate = sample_rate; audio_format = format; ret = 0; return ret; fail: if (playback_handle) { snd_pcm_close(playback_handle); playback_handle = NULL; } return ret; }
bool CASDeviceAlsa::Init( const char *pcDev, bool bIsOutput ) { int iErr; if( ( iErr = snd_pcm_open( &m_poHandle, pcDev, ( bIsOutput ? SND_PCM_STREAM_PLAYBACK : SND_PCM_STREAM_CAPTURE ), 0 ) ) < 0 ) AS_ERROR_RET( "cannot open audio device %s (%s)\n", pcDev, snd_strerror( iErr ) ); if( ( iErr = snd_pcm_hw_params_malloc( &m_poHW ) ) < 0 ) AS_ERROR_RET( "cannot allocate hardware parameter structure (%s)\n", snd_strerror( iErr ) ); if( ( iErr = snd_pcm_hw_params_any( m_poHandle, m_poHW ) ) < 0 ) AS_ERROR_RET( "cannot initialize hardware parameter structure (%s)\n", snd_strerror( iErr ) ); if( ( iErr = snd_pcm_hw_params_set_access( m_poHandle, m_poHW, SND_PCM_ACCESS_RW_INTERLEAVED ) ) < 0 ) AS_ERROR_RET( "cannot set access type (%s)\n", snd_strerror( iErr ) ); if( ( iErr = snd_pcm_hw_params_set_format( m_poHandle, m_poHW, SND_PCM_FORMAT_S16_LE ) ) < 0 ) AS_ERROR_RET( "cannot set sample format (%s)\n", snd_strerror( iErr ) ); unsigned int uiSF = m_uiSampleFreq; if( ( iErr = snd_pcm_hw_params_set_rate_near( m_poHandle, m_poHW, &uiSF, 0 ) ) < 0 ) AS_ERROR_RET( "cannot set sample rate (%s)\n", snd_strerror( iErr ) ); if( uiSF != m_uiSampleFreq ) { fprintf(stderr, "cannot set requested sample rate, asked for %d got %d\n", m_uiSampleFreq, uiSF ); m_uiSampleFreq = uiSF; } if( ( iErr = snd_pcm_hw_params_set_channels( m_poHandle, m_poHW, 2 ) ) < 0 ) AS_ERROR_RET( "cannot set channel count (%s)\n", snd_strerror( iErr ) ); /* m_uiFragments = 2; // http://www.bel.fi/~alankila/blog/2005/08/21/Full%20Duplex%20ALSA.html //if( ( iErr = snd_pcm_hw_params_set_periods( m_poHandle, m_poHW, 2, 0 ) ) < 0 ) if( ( iErr = snd_pcm_hw_params_set_periods_near( m_poHandle, m_poHW, &m_uiFragments, 0 ) ) < 0 ) AS_ERROR_RET( "cannot periods (%s)\n", snd_strerror( iErr ) ); */ // ?? //if( ( iErr = snd_pcm_hw_params_set_period_size( m_poHandle, m_poHW, m_uliBufferSamples, 0 ) ) < 0 ) // AS_ERROR_RET( "cannot set period size (%s)\n", snd_strerror( iErr ) ); snd_pcm_uframes_t oBS = m_uiBufferSamples; /* //unsigned int uiFrameSize = m_uiChannels * ( m_uiSampleDepth / 8 ); unsigned int uiFrag = oBS % m_uiFragments; if( uiFrag ) { oBS += m_uiFragments - uiFrag; } */ //printf( "> frames: %li\n", oBS ); if( ( iErr = snd_pcm_hw_params_set_buffer_size_near( m_poHandle, m_poHW, &oBS ) ) < 0 ) AS_ERROR_RET( "cannot set buffer size (%s)\n", snd_strerror( iErr ) ); if( oBS != m_uiBufferSamples ) { fprintf(stderr, "Could not set requested buffer size, asked for %d got %li\n", m_uiBufferSamples, oBS ); m_uiBufferSamples = oBS; } /* unsigned int frame_size = m_uiChannels * (m_uiSampleDepth / 8); snd_pcm_uframes_t frames = m_uiBufferSamples / frame_size * m_uiFragments; printf( "> frames: %li\n", frames ); if ((iErr = snd_pcm_hw_params_set_buffer_size_near(m_poHandle, m_poHW, &frames)) < 0) { AS_ERROR_RET( "Error setting buffer_size %li frames: %s\n", frames, snd_strerror(iErr)); return 1; } if (m_uiBufferSamples != frames * frame_size / m_uiFragments) { AS_ERROR_RET( "Could not set requested buffer size, asked for %d got %li\n", m_uiBufferSamples, frames * frame_size / m_uiFragments); m_uiBufferSamples = frames * frame_size / m_uiFragments; } */ if( ( iErr = snd_pcm_hw_params( m_poHandle, m_poHW ) ) < 0 ) AS_ERROR_RET( "cannot set parameters (%s)\n", snd_strerror( iErr ) ); CreateBuffer(); if( !bIsOutput ) return true; // tell ALSA to wake us up whenever m_sliBufferSize or more frames // of playback data can be delivered. Also, tell // ALSA that we'll start the device ourselves. if( ( iErr = snd_pcm_sw_params_malloc( &m_poSW ) ) < 0 ) AS_ERROR_RET( "cannot allocate software parameters structure (%s)\n", snd_strerror( iErr )); if( ( iErr = snd_pcm_sw_params_current( m_poHandle, m_poSW ) ) < 0 ) AS_ERROR_RET( "cannot initialize software parameters structure (%s)\n", snd_strerror( iErr )); // doesn't work when recording! //if( ( iErr = snd_pcm_sw_params_set_avail_min( m_poHandle, poParamSW, m_sliBufferSize ) ) < 0 ) // AS_ERROR_RET( "cannot set minimum available count (%s)\n", snd_strerror( iErr ) ); if( ( iErr = snd_pcm_sw_params_set_start_threshold( m_poHandle, m_poSW, 0U ) ) < 0 ) AS_ERROR_RET( "cannot set start mode (%s)\n", snd_strerror( iErr ) ); if( ( iErr = snd_pcm_sw_params( m_poHandle, m_poSW ) ) < 0 ) AS_ERROR_RET( "cannot set software parameters (%s)\n", snd_strerror( iErr ) ); return true; }
void init_alsa() { // long loops; //number of periods int rc; //for error check int size; //size of 1 period in snd_pcm_t *handle; snd_pcm_hw_params_t *params; unsigned int val; int dir; snd_pcm_uframes_t frames; // char *buffer; /* Open PCM device for playback. */ rc = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, SND_PCM_ASYNC |SND_PCM_NONBLOCK); if (rc < 0) { fprintf(stderr, "unable to open pcm device: %s\n", snd_strerror(rc)); exit(1); } handlec=handle; /* Allocate a hardware parameters object. */ snd_pcm_hw_params_alloca(¶ms); /* Fill it in with default values. */ snd_pcm_hw_params_any(handle, params); /* Set the desired hardware parameters. */ /* Interleaved mode */ snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); /* Signed 16-bit little-endian format */ assert((snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE))==0); /* Two channels (stereo) */ snd_pcm_hw_params_set_channels(handle, params, 2); /* 44100 bits/second sampling rate (CD quality) */ val = 44100; snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir); /* Set period size to 32 frames. */ frames = 32; snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir); /* Write the parameters to the driver */ rc = snd_pcm_hw_params(handle, params); if (rc < 0) { fprintf(stderr, "unable to set hw parameters: %s\n", snd_strerror(rc)); exit(1); } /* Use a buffer large enough to hold one period */ snd_pcm_hw_params_get_period_size(params, &frames, &dir); fprintf(stderr,"Period framesize:%ld\n",(long)frames); //printf("Period dir:%ld\n",(long)dir); size = frames * 4; /* 2 bytes/sample, 2 channels */ /* We want to loop for 5 seconds */ snd_pcm_hw_params_get_period_time(params, &val, &dir); /* 5 seconds in microseconds divided by * period time */ //================================================================================== init_buffers(); // char c1, c2; // int range, freq; // initscr(); // noecho(); // raw(); // do { /* c1 = getch(); clear(); if(c1=='q'||c1=='w'||c1=='e'||c1=='r'||c1=='t'||c1=='y'||c1=='u'||c1=='i') { switch(c1) { case 'q': range = 1; break; case 'w': range = 2; break; case 'e': range = 4; break; case 'r': range = 8; break; case 't': range = 16; break; case 'y': range = 32; break; case 'u': range = 64; break; case 'i': range = 128; } } else if(c1=='1'||c1=='2'||c1=='3'||c1=='4'||c1=='5'||c1=='6'||c1=='7') { freq = ((int)(c1-'1')); compose_and_play(range,freq); compose_and_play(range,freq); // printw("function called\n"); } else{ break; } }while(1);*/ //================================================================================== /* snd_pcm_drain(handle); snd_pcm_close(handle); // free(buffer); free(buffer_array[0]); free(buffer_array[1]); free(buffer_array[2]); free(buffer_array[3]); free(buffer_array[4]); free(buffer_array[5]); free(buffer_array[6]); return 0; */ }
static int drvHostALSAAudioOpen(bool fIn, PALSAAUDIOSTREAMCFG pCfgReq, PALSAAUDIOSTREAMCFG pCfgObt, snd_pcm_t **pphPCM) { snd_pcm_t *phPCM = NULL; int rc; unsigned int cChannels = pCfgReq->nchannels; unsigned int uFreq = pCfgReq->freq; snd_pcm_uframes_t obt_buffer_size; do { const char *pszDev = fIn ? s_ALSAConf.pcm_name_in : s_ALSAConf.pcm_name_out; if (!pszDev) { LogRel(("ALSA: Invalid or no %s device name set\n", fIn ? "input" : "output")); rc = VERR_INVALID_PARAMETER; break; } int err = snd_pcm_open(&phPCM, pszDev, fIn ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); if (err < 0) { LogRel(("ALSA: Failed to open \"%s\" as %s: %s\n", pszDev, fIn ? "ADC" : "DAC", snd_strerror(err))); rc = VERR_GENERAL_FAILURE; /** @todo Find a better rc. */ break; } snd_pcm_hw_params_t *pHWParms; snd_pcm_hw_params_alloca(&pHWParms); /** @todo Check for successful allocation? */ err = snd_pcm_hw_params_any(phPCM, pHWParms); if (err < 0) { LogRel(("ALSA: Failed to initialize hardware parameters: %s\n", snd_strerror(err))); rc = VERR_GENERAL_FAILURE; /** @todo Find a better rc. */ break; } err = snd_pcm_hw_params_set_access(phPCM, pHWParms, SND_PCM_ACCESS_RW_INTERLEAVED); if (err < 0) { LogRel(("ALSA: Failed to set access type: %s\n", snd_strerror(err))); rc = VERR_GENERAL_FAILURE; /** @todo Find a better rc. */ break; } err = snd_pcm_hw_params_set_format(phPCM, pHWParms, pCfgReq->fmt); if (err < 0) { LogRel(("ALSA: Failed to set audio format to %d: %s\n", pCfgReq->fmt, snd_strerror(err))); rc = VERR_GENERAL_FAILURE; /** @todo Find a better rc. */ break; } err = snd_pcm_hw_params_set_rate_near(phPCM, pHWParms, &uFreq, 0); if (err < 0) { LogRel(("ALSA: Failed to set frequency to %dHz: %s\n", pCfgReq->freq, snd_strerror(err))); rc = VERR_GENERAL_FAILURE; /** @todo Find a better rc. */ break; } err = snd_pcm_hw_params_set_channels_near(phPCM, pHWParms, &cChannels); if (err < 0) { LogRel(("ALSA: Failed to set number of channels to %d\n", pCfgReq->nchannels)); rc = VERR_GENERAL_FAILURE; /** @todo Find a better rc. */ break; } if ( cChannels != 1 && cChannels != 2) { LogRel(("ALSA: Number of audio channels (%u) not supported\n", cChannels)); rc = VERR_GENERAL_FAILURE; /** @todo Find a better rc. */ break; } unsigned int period_size = pCfgReq->period_size; unsigned int buffer_size = pCfgReq->buffer_size; if ( !((fIn && s_ALSAConf.size_in_usec_in) || (!fIn && s_ALSAConf.size_in_usec_out))) { if (!buffer_size) { buffer_size = DEFAULT_BUFFER_SIZE; period_size = DEFAULT_PERIOD_SIZE; } } if (buffer_size) { if ( ( fIn && s_ALSAConf.size_in_usec_in) || (!fIn && s_ALSAConf.size_in_usec_out)) { if (period_size) { err = snd_pcm_hw_params_set_period_time_near(phPCM, pHWParms, &period_size, 0); if (err < 0) { LogRel(("ALSA: Failed to set period time %d\n", pCfgReq->period_size)); rc = VERR_GENERAL_FAILURE; /** @todo Find a better rc. */ break; } } err = snd_pcm_hw_params_set_buffer_time_near(phPCM, pHWParms, &buffer_size, 0); if (err < 0) { LogRel(("ALSA: Failed to set buffer time %d\n", pCfgReq->buffer_size)); rc = VERR_GENERAL_FAILURE; /** @todo Find a better rc. */ break; } } else { snd_pcm_uframes_t period_size_f = (snd_pcm_uframes_t)period_size; snd_pcm_uframes_t buffer_size_f = (snd_pcm_uframes_t)buffer_size; snd_pcm_uframes_t minval; if (period_size_f) { minval = period_size_f; int dir = 0; err = snd_pcm_hw_params_get_period_size_min(pHWParms, &minval, &dir); if (err < 0) { LogRel(("ALSA: Could not determine minimal period size\n")); rc = VERR_GENERAL_FAILURE; /** @todo Find a better rc. */ break; } else { LogFunc(("Minimal period size is: %ld\n", minval)); if (period_size_f < minval) { if ( ( fIn && s_ALSAConf.period_size_in_overriden) || (!fIn && s_ALSAConf.period_size_out_overriden)) { LogFunc(("Period size %RU32 is less than minimal period size %RU32\n", period_size_f, minval)); } period_size_f = minval; } } err = snd_pcm_hw_params_set_period_size_near(phPCM, pHWParms, &period_size_f, 0); LogFunc(("Period size is: %RU32\n", period_size_f)); if (err < 0) { LogRel(("ALSA: Failed to set period size %d (%s)\n", period_size_f, snd_strerror(err))); rc = VERR_GENERAL_FAILURE; /** @todo Find a better rc. */ break; } } /* Calculate default buffer size here since it might have been changed * in the _near functions */ buffer_size_f = 4 * period_size_f; minval = buffer_size_f; err = snd_pcm_hw_params_get_buffer_size_min(pHWParms, &minval); if (err < 0) { LogRel(("ALSA: Could not retrieve minimal buffer size\n")); rc = VERR_GENERAL_FAILURE; /** @todo Find a better rc. */ break; } else { LogFunc(("Minimal buffer size is: %RU32\n", minval)); if (buffer_size_f < minval) { if ( ( fIn && s_ALSAConf.buffer_size_in_overriden) || (!fIn && s_ALSAConf.buffer_size_out_overriden)) { LogFunc(("Buffer size %RU32 is less than minimal buffer size %RU32\n", buffer_size_f, minval)); } buffer_size_f = minval; } } err = snd_pcm_hw_params_set_buffer_size_near(phPCM, pHWParms, &buffer_size_f); LogFunc(("Buffer size is: %RU32\n", buffer_size_f)); if (err < 0) { LogRel(("ALSA: Failed to set buffer size %d: %s\n", buffer_size_f, snd_strerror(err))); rc = VERR_GENERAL_FAILURE; /** @todo Find a better rc. */ break; } } } else LogFunc(("Warning: Buffer size is not set\n")); err = snd_pcm_hw_params(phPCM, pHWParms); if (err < 0) { LogRel(("ALSA: Failed to apply audio parameters\n")); rc = VERR_GENERAL_FAILURE; /** @todo Find a better rc. */ break; } err = snd_pcm_hw_params_get_buffer_size(pHWParms, &obt_buffer_size); if (err < 0) { LogRel(("ALSA: Failed to get buffer size\n")); rc = VERR_GENERAL_FAILURE; /** @todo Find a better rc. */ break; } snd_pcm_uframes_t obt_period_size; int dir = 0; err = snd_pcm_hw_params_get_period_size(pHWParms, &obt_period_size, &dir); if (err < 0) { LogRel(("ALSA: Failed to get period size\n")); rc = VERR_GENERAL_FAILURE; /** @todo Find a better rc. */ break; } LogFunc(("Freq=%dHz, period size=%RU32, buffer size=%RU32\n", pCfgReq->freq, obt_period_size, obt_buffer_size)); err = snd_pcm_prepare(phPCM); if (err < 0) { LogRel(("ALSA: Could not prepare hPCM %p\n", (void *)phPCM)); rc = VERR_GENERAL_FAILURE; /** @todo Find a better rc. */ break; } if ( !fIn && s_ALSAConf.threshold) { unsigned uShift; rc = drvHostALSAAudioALSAGetShift(pCfgReq->fmt, &uShift); if (RT_SUCCESS(rc)) { int bytes_per_sec = uFreq << (cChannels == 2) << uShift; snd_pcm_uframes_t threshold = (s_ALSAConf.threshold * bytes_per_sec) / 1000; rc = drvHostALSAAudioSetThreshold(phPCM, threshold); } } else rc = VINF_SUCCESS; } while (0); if (RT_SUCCESS(rc)) { pCfgObt->fmt = pCfgReq->fmt; pCfgObt->nchannels = cChannels; pCfgObt->freq = uFreq; pCfgObt->samples = obt_buffer_size; *pphPCM = phPCM; } else drvHostALSAAudioClose(&phPCM); LogFlowFuncLeaveRC(rc); return rc; }
int ao_plugin_open(ao_device *device, ao_sample_format *format) { ao_alsa_internal *internal = (ao_alsa_internal *) device->internal; snd_pcm_channel_params_t param; int err; memset(¶m, 0, sizeof(param)); param.channel = SND_PCM_CHANNEL_PLAYBACK; param.mode = SND_PCM_MODE_BLOCK; param.format.interleave = 1; switch (format->bits) { case 8 : param.format.format = SND_PCM_SFMT_S8; break; case 16 : param.format.format = device->client_byte_format == AO_FMT_BIG ? SND_PCM_SFMT_S16_BE : SND_PCM_SFMT_S16_LE; device->driver_byte_format = device->client_byte_format; break; default : return 0; } if (format->channels == 1 || format->channels == 2) param.format.voices = format->channels; else return 0; /* Finish filling in the parameter structure */ param.format.rate = format->rate; param.start_mode = SND_PCM_START_FULL; param.stop_mode = SND_PCM_STOP_STOP; param.buf.block.frag_size = internal->buf_size; param.buf.block.frags_min = 1; param.buf.block.frags_max = 8; internal->buf = malloc(internal->buf_size); internal->buf_end = 0; if (internal->buf == NULL) return 0; /* Could not alloc swap buffer */ /* Open the ALSA device */ err = snd_pcm_open(&(internal->pcm_handle), internal->card, internal->dev, SND_PCM_OPEN_PLAYBACK | SND_PCM_OPEN_NONBLOCK); if (err < 0) { free(internal->buf); return 0; } err = snd_pcm_channel_params(internal->pcm_handle, ¶m); if (err < 0) { snd_pcm_close(internal->pcm_handle); free(internal->buf); return 0; } snd_pcm_nonblock_mode(internal->pcm_handle, 0); snd_pcm_channel_prepare(internal->pcm_handle, SND_PCM_CHANNEL_PLAYBACK); return 1; }
main(int argc, char *argv[]) { FILE *fp; int fd,arg; snd_pcm_t *handle; snd_pcm_hw_params_t *hw_params; int rate=8000; float f[WINDOW],hann[WINDOW],w[WINDOW],w2[WINDOW],s0,s1=0,tot; float ac[ORDER+1],lcp[ORDER+1],lsp[ORDER],l[ORDER],weight[ORDER],delta,d; short sample,s[160],buf[2000]; int i,j,n,b,toggle=1; float e,laste=0; int ebit=ETOPBIT, ebuff=0; int sound=0; // boolean start/stop float f2[FFT],min; float real[FFT],imag[FFT]; int dummy[100000]; float amp[WINDOW],pha[WINDOW]; int frame=0; SpeexPreprocessState *st; for (i=0; i<8; i++) report[i]=0; st = speex_preprocess_state_init(160, 8000); i=1; speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DENOISE, &i); // i=1; // speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DEREVERB, &i); // e=.0; // speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DEREVERB_DECAY, &e); // e=.0; // speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &e); setup_twiddles(realtwiddle,imtwiddle,FFT); for (i=0; i<WINDOW; i++) f[i]=0; for (i=0; i<ORDER; i++) {last[i]=0; last2[i]=0;} for(i=0; i<WINDOW; i++) hann[i]=0.5-0.5*cos(2.0*M_PI*i/(WINDOW-1)); if (argc==2) training=atoi(argv[1]); fprintf(stderr,"training=%i\n",training); // exit(0); cbsize=0; start[0]=0; size[0]=0; if (training==0) if (fp=fopen("cb.txt","r")) { while(!feof(fp)) { fscanf(fp,"%i\n",&size[cbsize]); for (i=start[cbsize]; i<start[cbsize]+size[cbsize]; i++) { for (n=1; n<FF2-1; n++) fscanf(fp,"%f,",&cb[i][n]); fscanf(fp,"\n"); } start[cbsize+1]=start[cbsize]+size[cbsize]; cbsize++; } fclose(fp); } //for (i=0; i<cbsize; i++) printf("%i,\n",size[i]); exit(0); //--------------------------------- fp=fopen("/tmp/b.raw","w"); snd_pcm_open(&handle, "default", SND_PCM_STREAM_CAPTURE, 0); snd_pcm_hw_params_malloc(&hw_params); snd_pcm_hw_params_any(handle, hw_params); snd_pcm_hw_params_set_access(handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED); snd_pcm_hw_params_set_format(handle, hw_params, SND_PCM_FORMAT_S16_LE); snd_pcm_hw_params_set_rate_near(handle, hw_params, &rate, 0); snd_pcm_hw_params_set_channels(handle, hw_params, 2); snd_pcm_hw_params(handle, hw_params); snd_pcm_hw_params_free(hw_params); snd_pcm_prepare(handle); //printf("sleep 1...\n"); sleep(1); printf("OK, go....\n"); while(1) { for (i=0; i<WINDOW-STEP; i++) f[i]=f[i+STEP]; // shift samples down if (toggle) { //read(fd,s,160*2); snd_pcm_readi(handle, buf, 160); for (i=0; i<160; i++) s[i]=buf[i*2]; speex_preprocess_run(st, s); } else bcopy(&s[80],s,80*2); toggle=!toggle; for (i=WINDOW-STEP,j=0; i<WINDOW; i++,j++) { sample=s[j]; s0=(float)sample; f[i]=s0-s1*EMPH; s1=s0; // 1.0 pre-emphasis fwrite(&sample,2,1,fp); } for (i=0; i<WINDOW; i++) w[i]=f[i]; // remove any DC level.... tot=0; for (i=0; i<WINDOW; i++) tot+=w[i]; tot/=WINDOW; for (i=0; i<WINDOW; i++) w[i]-=tot; for (i=0; i<WINDOW; i++) w[i]*=hann[i]; // window data autocorrelate(w,ac,WINDOW,ORDER); wld(&lpc[1],ac,ORDER); lpc[0]=1.0; // e=ac[0]; e=0;for(i=0; i<=ORDER; i++) e+=ac[i]*lpc[i]; if (e<0) e=0; if (e>TOL_OFF) ebuff|=ebit; else ebuff&=~ebit; // update energy bit-buffer ebit>>=1; if (ebit==0) ebit=ETOPBIT; // circular shift for (i=0; i<FFT; i++) {real[i]=0; imag[i]=0;} for (i=0; i<=ORDER; i++) real[i]=lpc[i]; simple_fft(real,imag,realtwiddle,imtwiddle,FFT); for (i=0; i<FF2; i++) { b=bin[i]; f2[i]=powf(real[b]*real[b]+imag[b]*imag[b],-0.5); //f2[i]=powf(f2[i],0.333333); //f2[i]=powf(f2[i],1.2); f2[i]=logf(f2[i]); } // spectral tilt compensation... for (i=1; i<FF2; i++) f2[i]=f2[i]*(float)(i+TILT)/TILT; // fold down to 9 bins... /* if (f2[FF2-2]>f2[FF2-3]) f2[FF2-3]=f2[FF2-2]; f2[FF2-2]=0; if (f2[FF2-4]>f2[FF2-5]) f2[FF2-5]=f2[FF2-4]; f2[FF2-4]=0; if (f2[FF2-9]>f2[FF2-10]) f2[FF2-10]=f2[FF2-9]; f2[FF2-9]=0; if (f2[FF2-11]>f2[FF2-12]) f2[FF2-12]=f2[FF2-11]; f2[FF2-11]=0; if (f2[FF2-13]>f2[FF2-14]) f2[FF2-14]=f2[FF2-13]; f2[FF2-13]=0; if (f2[FF2-15]>f2[FF2-16]) f2[FF2-16]=f2[FF2-15]; f2[FF2-15]=0; */ for (i=0; i<FF2; i++) { if (f2[i]>6.0) f2[i]=6.0; f2[i]*=100.0; } if (TRACE) { fprintf(stderr,"%.f,",e); for (i=1; i<FF2-1; i++) fprintf(stderr,"%.f,",f2[i]); fprintf(stderr,"\n");} // calculate frame delta.... delta=0; for (i=1; i<FF2-1; i++) {d=f2[i]-last[i]; delta+=d*d;} //printf("delta=%f\n",delta); if (sound==0 && e>TOL_ON && frame>200) { // start recording... bcopy(last2,&word[wsize],FF2*4); wsize++; bcopy(last,&word[wsize],FF2*4); wsize++; sound=1; wsize=0; bcopy(f2,&word[wsize],FF2*4); wsize++; bcopy(last,last2,FF2*4); bcopy(f2,last,FF2*4); } else if (sound==1 && e>TOL_OFF) { // continue reading word... bcopy(f2,&word[wsize],FF2*4); wsize++; if (wsize>200) wsize=200; bcopy(last,last2,FF2*4); bcopy(f2,last,FF2*4); } else if (sound==1 && ebuff==0) { // finised reading word // wsize-=8; // remove training silence (2 frame buffer) if (wsize>4 && wsize<50) { if (training>0) train(); else closest(); } sound=0; wsize=0; bcopy(last,last2,FF2*4); bcopy(f2,last,FF2*4); } //for (i=1; i<FF2-1; i++) printf("%.0f,",f2[i]); printf(" e=%f\n",e); laste=e; frame++; if (frame==37800) exit(0); } }
bool PAPlayer::CreateStream(int num, int channels, int samplerate, int bitspersample, CStdString codec) { snd_pcm_hw_params_t *hw_params=NULL; FreeStream(num); m_packet[num][0].packet = (BYTE*)malloc(PACKET_SIZE * PACKET_COUNT); for (int i = 1; i < PACKET_COUNT ; i++) m_packet[num][i].packet = m_packet[num][i - 1].packet + PACKET_SIZE; m_SampleRateOutput = channels>2?samplerate:XBMC_SAMPLE_RATE; m_BitsPerSampleOutput = 16; m_BytesPerSecond = (m_BitsPerSampleOutput / 8)*m_SampleRateOutput*channels; /* Open the device */ int nErr = snd_pcm_open(&m_pStream[num], g_guiSettings.GetString("audiooutput.audiodevice"), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); CHECK_ALSA_RETURN(LOGERROR,"pcm_open",nErr); /* Allocate Hardware Parameters structures and fills it with config space for PCM */ snd_pcm_hw_params_alloca(&hw_params); nErr = snd_pcm_hw_params_any(m_pStream[num], hw_params); CHECK_ALSA_RETURN(LOGERROR,"hw_params_any",nErr); nErr = snd_pcm_hw_params_set_access(m_pStream[num], hw_params, SND_PCM_ACCESS_RW_INTERLEAVED); CHECK_ALSA_RETURN(LOGERROR,"hw_params_set_access",nErr); // always use 16 bit samples nErr = snd_pcm_hw_params_set_format(m_pStream[num], hw_params, SND_PCM_FORMAT_S16_LE); CHECK_ALSA_RETURN(LOGERROR,"hw_params_set_format",nErr); nErr = snd_pcm_hw_params_set_rate_near(m_pStream[num], hw_params, &m_SampleRateOutput, NULL); CHECK_ALSA_RETURN(LOGERROR,"hw_params_set_rate",nErr); nErr = snd_pcm_hw_params_set_channels(m_pStream[num], hw_params, channels); CHECK_ALSA_RETURN(LOGERROR,"hw_params_set_channels",nErr); m_periods[num] = PACKET_SIZE / 4; nErr = snd_pcm_hw_params_set_period_size_near(m_pStream[num], hw_params, &m_periods[num], 0); CHECK_ALSA_RETURN(LOGERROR,"hw_params_set_period_size",nErr); snd_pcm_uframes_t buffer_size = PACKET_SIZE*20; // big enough buffer nErr = snd_pcm_hw_params_set_buffer_size_near(m_pStream[num], hw_params, &buffer_size); CHECK_ALSA_RETURN(LOGERROR,"hw_params_set_buffer_size",nErr); unsigned int periodDuration = 0; nErr = snd_pcm_hw_params_get_period_time(hw_params,&periodDuration, 0); CHECK_ALSA(LOGERROR,"hw_params_get_period_time",nErr); CLog::Log(LOGDEBUG,"PAPlayer::CreateStream - initialized. " "sample rate: %d, channels: %d, period size: %d, buffer size: %d " "period duration: %d", m_SampleRateOutput, channels, (int) m_periods[num], (int) buffer_size, periodDuration); /* Assign them to the playback handle and free the parameters structure */ nErr = snd_pcm_hw_params(m_pStream[num], hw_params); CHECK_ALSA_RETURN(LOGERROR,"snd_pcm_hw_params",nErr); /* disable underrun reporting and play silence */ nErr = snd_pcm_prepare (m_pStream[num]); CHECK_ALSA(LOGERROR,"snd_pcm_prepare",nErr); // create our resampler // upsample to XBMC_SAMPLE_RATE, only do this for sources with 1 or 2 channels m_resampler[num].InitConverter(samplerate, bitspersample, channels, m_SampleRateOutput, m_BitsPerSampleOutput, PACKET_SIZE); // set initial volume SetStreamVolume(num, g_stSettings.m_nVolumeLevel); // TODO: How do we best handle the callback, given that our samplerate etc. may be // changing at this point? // fire off our init to our callback if (m_pCallback) m_pCallback->OnInitialize(channels, m_SampleRateOutput, m_BitsPerSampleOutput); return true; }
static void *alsa_thread_init(const char *device, unsigned rate, unsigned latency) { alsa_thread_t *alsa = (alsa_thread_t*)calloc(1, sizeof(alsa_thread_t)); snd_pcm_hw_params_t *params = NULL; snd_pcm_sw_params_t *sw_params = NULL; const char *alsa_dev = device ? device : "default"; unsigned latency_usec = latency * 1000 / 2; unsigned channels = 2; unsigned periods = 4; snd_pcm_uframes_t buffer_size; snd_pcm_format_t format; if (!alsa) return NULL; TRY_ALSA(snd_pcm_open(&alsa->pcm, alsa_dev, SND_PCM_STREAM_PLAYBACK, 0)); TRY_ALSA(snd_pcm_hw_params_malloc(¶ms)); alsa->has_float = alsathread_find_float_format(alsa->pcm, params); format = alsa->has_float ? SND_PCM_FORMAT_FLOAT : SND_PCM_FORMAT_S16; TRY_ALSA(snd_pcm_hw_params_any(alsa->pcm, params)); TRY_ALSA(snd_pcm_hw_params_set_access( alsa->pcm, params, SND_PCM_ACCESS_RW_INTERLEAVED)); TRY_ALSA(snd_pcm_hw_params_set_format(alsa->pcm, params, format)); TRY_ALSA(snd_pcm_hw_params_set_channels(alsa->pcm, params, channels)); TRY_ALSA(snd_pcm_hw_params_set_rate(alsa->pcm, params, rate, 0)); TRY_ALSA(snd_pcm_hw_params_set_buffer_time_near( alsa->pcm, params, &latency_usec, NULL)); TRY_ALSA(snd_pcm_hw_params_set_periods_near( alsa->pcm, params, &periods, NULL)); TRY_ALSA(snd_pcm_hw_params(alsa->pcm, params)); /* Shouldn't have to bother with this, * but some drivers are apparently broken. */ if (snd_pcm_hw_params_get_period_size(params, &alsa->period_frames, NULL)) snd_pcm_hw_params_get_period_size_min( params, &alsa->period_frames, NULL); RARCH_LOG("ALSA: Period size: %d frames\n", (int)alsa->period_frames); if (snd_pcm_hw_params_get_buffer_size(params, &buffer_size)) snd_pcm_hw_params_get_buffer_size_max(params, &buffer_size); RARCH_LOG("ALSA: Buffer size: %d frames\n", (int)buffer_size); alsa->buffer_size = snd_pcm_frames_to_bytes(alsa->pcm, buffer_size); alsa->period_size = snd_pcm_frames_to_bytes(alsa->pcm, alsa->period_frames); TRY_ALSA(snd_pcm_sw_params_malloc(&sw_params)); TRY_ALSA(snd_pcm_sw_params_current(alsa->pcm, sw_params)); TRY_ALSA(snd_pcm_sw_params_set_start_threshold( alsa->pcm, sw_params, buffer_size / 2)); TRY_ALSA(snd_pcm_sw_params(alsa->pcm, sw_params)); snd_pcm_hw_params_free(params); snd_pcm_sw_params_free(sw_params); alsa->fifo_lock = slock_new(); alsa->cond_lock = slock_new(); alsa->cond = scond_new(); alsa->buffer = fifo_new(alsa->buffer_size); if (!alsa->fifo_lock || !alsa->cond_lock || !alsa->cond || !alsa->buffer) goto error; alsa->worker_thread = sthread_create(alsa_worker_thread, alsa); if (!alsa->worker_thread) { RARCH_ERR("error initializing worker thread"); goto error; } return alsa; error: RARCH_ERR("ALSA: Failed to initialize...\n"); if (params) snd_pcm_hw_params_free(params); if (sw_params) snd_pcm_sw_params_free(sw_params); alsa_thread_free(alsa); return NULL; }
int main() { long loops; int rc,i = 0; int size; FILE *fp ; snd_pcm_t *handle; snd_pcm_hw_params_t *params; unsigned int val,val2; int dir; snd_pcm_uframes_t frames; char *buffer; if( (fp =fopen("sound.wav","w")) < 0) printf("open sound.wav fial\n"); /* Open PCM device for recording (capture). */ rc = snd_pcm_open(&handle, "default", SND_PCM_STREAM_CAPTURE, 0); if (rc < 0) { fprintf(stderr, "unable to open pcm device: %s/n", snd_strerror(rc)); exit(1); } /* Allocate a hardware parameters object. */ snd_pcm_hw_params_alloca(¶ms); /* Fill it in with default values. */ snd_pcm_hw_params_any(handle, params); /* Set the desired hardware parameters. */ /* Interleaved mode */ snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); /* Signed 16-bit little-endian format */ snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE); /* Two channels (stereo) */ snd_pcm_hw_params_set_channels(handle, params, 2); /* 44100 bits/second sampling rate (CD quality) */ val = 44100; snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir); /* Set period size to 32 frames. */ frames = 32; snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir); /* Write the parameters to the driver */ rc = snd_pcm_hw_params(handle, params); if (rc < 0) { fprintf(stderr, "unable to set hw parameters: %s/n", snd_strerror(rc)); exit(1); } /* Use a buffer large enough to hold one period */ snd_pcm_hw_params_get_period_size(params, &frames, &dir); size = frames * 4; /* 2 bytes/sample, 2 channels */ printf("size = %d\n",size); buffer = (char *) malloc(size); /* We want to loop for 5 seconds */ snd_pcm_hw_params_get_period_time(params, &val, &dir); loops = 10000000 / val; while (loops > 0) { loops--; rc = snd_pcm_readi(handle, buffer, frames); printf("%d\n",i++); if (rc == -EPIPE) { /* EPIPE means overrun */ fprintf(stderr, "overrun occurred/n"); snd_pcm_prepare(handle); } else if (rc < 0) { fprintf(stderr, "error from read: %s/n", snd_strerror(rc)); } else if (rc != (int)frames) { fprintf(stderr, "short read, read %d frames/n", rc); } //rc = fwrite( buffer,1, size,fp); rc = write(1,buffer,size); if (rc != size) fprintf(stderr, "short write: wrote %d bytes/n", rc); else printf("fwrite buffer success\n"); } /******************打印参数*********************/ snd_pcm_hw_params_get_channels(params, &val); printf("channels = %d\n", val); snd_pcm_hw_params_get_rate(params, &val, &dir); printf("rate = %d bps\n", val); snd_pcm_hw_params_get_period_time(params, &val, &dir); printf("period time = %d us\n", val); snd_pcm_hw_params_get_period_size(params, &frames, &dir); printf("period size = %d frames\n", (int)frames); snd_pcm_hw_params_get_buffer_time(params, &val, &dir); printf("buffer time = %d us\n", val); snd_pcm_hw_params_get_buffer_size(params, (snd_pcm_uframes_t *) &val); printf("buffer size = %d frames\n", val); snd_pcm_hw_params_get_periods(params, &val, &dir); printf("periods per buffer = %d frames\n", val); snd_pcm_hw_params_get_rate_numden(params, &val, &val2); printf("exact rate = %d/%d bps\n", val, val2); val = snd_pcm_hw_params_get_sbits(params); printf("significant bits = %d\n", val); //snd_pcm_hw_params_get_tick_time(params, &val, &dir); printf("tick time = %d us\n", val); val = snd_pcm_hw_params_is_batch(params); printf("is batch = %d\n", val); val = snd_pcm_hw_params_is_block_transfer(params); printf("is block transfer = %d\n", val); val = snd_pcm_hw_params_is_double(params); printf("is double = %d\n", val); val = snd_pcm_hw_params_is_half_duplex(params); printf("is half duplex = %d\n", val); val = snd_pcm_hw_params_is_joint_duplex(params); printf("is joint duplex = %d\n", val); val = snd_pcm_hw_params_can_overrange(params); printf("can overrange = %d\n", val); val = snd_pcm_hw_params_can_mmap_sample_resolution(params); printf("can mmap = %d\n", val); val = snd_pcm_hw_params_can_pause(params); printf("can pause = %d\n", val); val = snd_pcm_hw_params_can_resume(params); printf("can resume = %d\n", val); val = snd_pcm_hw_params_can_sync_start(params); printf("can sync start = %d\n", val); /*******************************************************************/ snd_pcm_drain(handle); snd_pcm_close(handle); fclose(fp); free(buffer); return 0; }
static int alsa_stream(const char *pdevice, const char *cdevice, int latency) { snd_pcm_t *phandle, *chandle; char *buffer; int err; ssize_t r; struct final_params negotiated; snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE; char pdevice_new[32]; err = snd_output_stdio_attach(&output, error_fp, 0); if (err < 0) { fprintf(error_fp, "alsa: Output failed: %s\n", snd_strerror(err)); return 0; } /* Open the devices */ if ((err = snd_pcm_open(&phandle, pdevice, SND_PCM_STREAM_PLAYBACK, 0)) < 0) { fprintf(error_fp, "alsa: Cannot open playback device %s: %s\n", pdevice, snd_strerror(err)); return 0; } if ((err = snd_pcm_open(&chandle, cdevice, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK)) < 0) { fprintf(error_fp, "alsa: Cannot open capture device %s: %s\n", cdevice, snd_strerror(err)); snd_pcm_close(phandle); return 0; } err = setparams(phandle, chandle, format, latency, 0, &negotiated); /* Try to use plughw instead, as it allows emulating speed */ if (err == 2 && strncmp(pdevice, "hw", 2) == 0) { snd_pcm_close(phandle); sprintf(pdevice_new, "plug%s", pdevice); pdevice = pdevice_new; if (verbose) fprintf(error_fp, "alsa: Trying %s for playback\n", pdevice); if ((err = snd_pcm_open(&phandle, pdevice, SND_PCM_STREAM_PLAYBACK, 0)) < 0) { fprintf(error_fp, "alsa: Cannot open playback device %s: %s\n", pdevice, snd_strerror(err)); snd_pcm_close(chandle); return 0; } err = setparams(phandle, chandle, format, latency, 1, &negotiated); } if (err != 0) { fprintf(error_fp, "alsa: setparams failed\n"); snd_pcm_close(phandle); snd_pcm_close(chandle); return 1; } buffer = malloc((negotiated.bufsize * snd_pcm_format_width(format) / 8) * negotiated.channels); if (buffer == NULL) { fprintf(error_fp, "alsa: Failed allocating buffer for audio\n"); snd_pcm_close(phandle); snd_pcm_close(chandle); return 0; } if (verbose) fprintf(error_fp, "alsa: stream started from %s to %s (%i Hz, buffer delay = %.2f ms)\n", cdevice, pdevice, negotiated.rate, negotiated.latency * 1000.0 / negotiated.rate); while (!stop_alsa) { /* We start with a read and not a wait to auto(re)start the capture */ r = readbuf(chandle, buffer, negotiated.bufsize); if (r == 0) /* Succesfully recovered from an overrun? */ continue; /* Force restart of capture stream */ if (r > 0) writebuf(phandle, buffer, r); /* use poll to wait for next event */ while (!stop_alsa && !snd_pcm_wait(chandle, 50)) ; } snd_pcm_drop(chandle); snd_pcm_drop(phandle); snd_pcm_unlink(chandle); snd_pcm_hw_free(phandle); snd_pcm_hw_free(chandle); snd_pcm_close(phandle); snd_pcm_close(chandle); return 0; }
int main(int argc, char *argv[]) { ros::init(argc, argv, "cmd_control"); ros::NodeHandle n; ros::Publisher motor_pub = n.advertise<std_msgs::Char>("motor_chatter", 1000); std::string port; ros::param::param<std::string>("~port", port, "/dev/ttyACM0"); int baud; ros::param::param<int>("~baud", baud, 57600); int byte_per_sample = bits_per_sample >> 3; long loops; int rc; int size; snd_pcm_t *handle; snd_pcm_hw_params_t *params; unsigned int val; int dir; snd_pcm_uframes_t frames; char *buffer; char *speechbuf; /* Open PCM device for recording (capture). */ rc = snd_pcm_open(&handle, "default", SND_PCM_STREAM_CAPTURE, 0); if (rc < 0) { fprintf(stderr, "unable to open pcm device: %s\n", snd_strerror(rc)); exit(1); } /* Allocate a hardware parameters object. */ snd_pcm_hw_params_alloca(¶ms); /* Fill it in with default values. */ snd_pcm_hw_params_any(handle, params); /* Set the desired hardware parameters. */ /* Interleaved mode */ snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); /* Signed 16-bit little-endian format */ snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE); /* Two channels (stereo) */ snd_pcm_hw_params_set_channels(handle, params, channels); /* 44100 bits/second sampling rate (CD quality) */ //val = 44100; val = sample_rate; snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir); /* Set period size to 32 frames. */ frames = frames_per_period; snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir); /* Write the parameters to the driver */ rc = snd_pcm_hw_params(handle, params); if (rc < 0) { fprintf(stderr, "unable to set hw parameters: %s\n", snd_strerror(rc)); exit(1); } /* Use a buffer large enough to hold one period */ snd_pcm_hw_params_get_period_size(params, &frames, &dir); size = frames * channels * byte_per_sample; /* 2 bytes/sample, 1 channels */ speechbuf = (char *) malloc(size); //printf("buffer size %d\n", size); /* We want to loop for 5 seconds */ snd_pcm_hw_params_get_period_time(params, &val, &dir); int client_sockfd; struct sockaddr_in remote_addr; //服务器端网络地址结构体 memset(&remote_addr,0,sizeof(remote_addr)); //数据初始化--清零 remote_addr.sin_family=AF_INET; //设置为IP通信 remote_addr.sin_addr.s_addr=inet_addr("10.0.1.0");//服务器IP地址 remote_addr.sin_port=htons(port); //服务器端口号 /*创建客户端套接字--IPv4协议,面向连接通信,TCP协议*/ if((client_sockfd=socket(PF_INET,SOCK_STREAM,0))<0) { perror("socket failed\n"); return 1; } /*将套接字绑定到服务器的网络地址上*/ if(connect(client_sockfd,(struct sockaddr *)&remote_addr,sizeof(struct sockaddr))<0) { perror("connect failed\n"); return 1; } printf("connected to server\n"); int len = 10 * FRAME_LEN; //printf("pcm size is %d", pcm_size); int totallen = 0; totallen = 0; int sendlen =0; int pcm_count = 0; int num = 0; pthread_t thread_recv; int err; void *tret; if((err = pthread_create(&thread_recv, NULL, &recv_cmd_func, &client_sockfd)) != 0) { printf("thread recv erro : %s \n", strerror(err)); return -1; } sleep(1); //printf("thread creat is\n" ); //fflush(stdout); while(1) { rc = snd_pcm_readi(handle, speechbuf, frames); if (rc == -EPIPE) { /* EPIPE means overrun */ fprintf(stderr, "overrun occurred\n"); snd_pcm_prepare(handle); } else if (rc < 0) { fprintf(stderr, "error from read: %s\n", snd_strerror(rc)); } else if (rc != (int)frames) { fprintf(stderr, "short read, read %d frames\n", rc); break; } sendlen = send(client_sockfd, speechbuf, len, 0); if(sendlen < 0) printf("send failed \n"); } if((err = pthread_join(thread_recv, &tret)) != 0) { printf("can not join thread_recv %s!\n", strerror(err)); exit(-1); } getchar(); close(client_sockfd); snd_pcm_drain(handle); snd_pcm_close(handle); free(speechbuf); return 0; }
int main() { int result; snd_pcm_t *handle = NULL; snd_pcm_hw_params_t *params = NULL; snd_pcm_uframes_t frames; snd_pcm_access_t access; snd_pcm_format_t format; unsigned int rate = 44100; unsigned int val, val2; int dir = 0; const char *device = getenv ("ALSA_DEFAULT"); if (device == NULL) { device = "default"; } result = snd_pcm_open(&handle, device, SND_PCM_STREAM_PLAYBACK, 0); if (result < 0) showErrorAndExit(result, "Error: Unable to open PCM device: %s\n"); result = snd_pcm_hw_params_malloc(¶ms); if (result < 0) showErrorAndExit(result, "Error: No memory for hardware parameters: %s\n"); result = snd_pcm_hw_params_any(handle, params); if (result < 0) showErrorAndExit(result, "Error: Cannot read HW params: %s\n"); result = snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); if (result < 0) showErrorAndExit(result, "Could not set access method: %s\n"); result = snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE); if (result < 0) showErrorAndExit(result, "Error: Could not set output format: %s\n"); result = snd_pcm_hw_params_set_channels(handle, params, 1); if (result < 0) showErrorAndExit(result, "Error: Cannot set to 1 channel: %s\n"); result = snd_pcm_hw_params_set_rate_near(handle, params, &rate, &dir); if (result < 0) showErrorAndExit(result, "Error: Could not set rate: %s\n"); result = snd_pcm_hw_params(handle, params); if (result < 0) showErrorAndExit(result, "Error: Could not write HW params: %s\n"); printf("Card Parameters\n"); printf("%30s: %s\n", "Alsa Library Version", snd_asoundlib_version()); result = snd_pcm_hw_params_get_access(params, &access); if (result < 0) { showErrorAndExit(result, "Error: Could not retrieve access mode: %s\n"); } else { printf("%30s: %s\n", "Access Method", snd_pcm_access_name(access)); } result = snd_pcm_hw_params_get_format(params, &format); if (result < 0) { showErrorAndExit(result, "Error: Unable to retrieve format type: %d\n"); } else { printf("%30s: %s\n", "Format", snd_pcm_format_name(format)); } result = snd_pcm_hw_params_get_channels(params, &val); if (result < 0) { showErrorAndExit(result, "Error: Unable to retrieve channel count: %s\n"); } else { printf("%30s: %d\n", "Channels", val); } result = snd_pcm_hw_params_get_rate(params, &val, &dir); if (result < 0) { showErrorAndExit(result, "Error: Unable to retrieve rate: %s\n"); } else { printf("%30s: %d bps\n", "Rate", val); } result = snd_pcm_hw_params_get_period_time(params, &val, &dir); if (result < 0) { showErrorAndExit(result, "Error: Unable to retrieve period time: %s\n"); } else { printf("%30s: %d us\n", "Period Time", val); } result = snd_pcm_hw_params_get_period_size(params, &frames, &dir); if (result < 0) { showErrorAndExit(result, "Error: Unable to retrieve period size: %s\n"); } else { printf("%30s: %d frames\n", "Period Size", (int) frames); } result = snd_pcm_hw_params_get_buffer_time(params, &val, &dir); if (result < 0) { showErrorAndExit(result, "Error: Unable to retrieve buffer time: %s\n"); } else { printf("%30s: %d us\n", "Buffer Time", val); } result = snd_pcm_hw_params_get_buffer_size(params, &frames); if (result < 0) { showErrorAndExit(result, "Error: Unable to retrieve buffer size: %s\n"); } else { printf("%30s: %d frames\n", "Buffer Size", (int) frames); } result = snd_pcm_hw_params_get_periods(params, &val, &dir); if (result < 0) { showErrorAndExit(result, "Error: Unable to get buffer periods: %s\n"); } else { printf("%30s: %d frames\n", "Periods per Buffer", val); } result = snd_pcm_hw_params_get_rate_numden(params, &val, &val2); if (result < 0) { showErrorAndExit(result, "Error: Unable to get rate numerator/denominator: %s\n"); } else { printf("%30s: %d/%d bps\n", "Exact Rate", val, val2); } val = snd_pcm_hw_params_get_sbits(params); printf("%30s: %d\n", "Significant Bits", val); result = snd_pcm_hw_params_get_tick_time(params, &val, &dir); if (result < 0) { showErrorAndExit(result, "Error: Could not retrieve tick time: %s\n"); } else { printf("%30s: %d\n", "Tick Time", val); } printf("Card Capabilities\n"); val = snd_pcm_hw_params_is_batch(params); printf("%30s: %s\n", "Batch Transfer", (val ? "Yes" : "No")); val = snd_pcm_hw_params_is_block_transfer(params); printf("%30s: %s\n", "Block Transfer", (val ? "Yes" : "No")); val = snd_pcm_hw_params_is_double(params); printf("%30s: %s\n", "Double Buffering", (val ? "Yes" : "No")); val = snd_pcm_hw_params_is_half_duplex(params); printf("%30s: %s\n", "Half Duplex Only", (val ? "Yes" : "No")); val = snd_pcm_hw_params_is_joint_duplex(params); printf("%30s: %s\n", "Joint Duplex Capable", (val ? "Yes" : "No")); val = snd_pcm_hw_params_can_overrange(params); printf("%30s: %s\n", "Support Overrange Detection", (val ? "Yes" : "No")); val = snd_pcm_hw_params_can_mmap_sample_resolution(params); printf("%30s: %s\n", "Support Sample-res Mmap", (val ? "Yes" : "No")); val = snd_pcm_hw_params_can_pause(params); printf("%30s: %s\n", "Can Pause", (val ? "Yes" : "No")); val = snd_pcm_hw_params_can_resume(params); printf("%30s: %s\n", "Can Resume", (val ? "Yes" : "No")); val = snd_pcm_hw_params_can_sync_start(params); printf("%30s: %s\n", "Support Sync Start", (val ? "Yes" : "No")); result = snd_pcm_close(handle); if (result < 0) showErrorAndExit(result, "Error: Could not close PCM device: %s\n"); return 0; }
void create_recorder(int samp_rate,char* dev_name,int nchan,void **capture_handle_f) { int err; snd_pcm_t *capture_handle; snd_pcm_hw_params_t *hw_params; printf("From C: *capture_handle_f=%p\n",*capture_handle_f); if ((err = snd_pcm_open ((snd_pcm_t**)capture_handle_f, dev_name, SND_PCM_STREAM_CAPTURE, 0)) < 0) { fprintf (stderr, "cannot open audio device %s (%s)\n", dev_name, snd_strerror (err)); fprintf(stderr, "Hint: Use \"arecord -l\" to list recording devices.\n"); exit (1); } capture_handle = (snd_pcm_t*)(*capture_handle_f); printf("made handle %p (&=%p) to %s at %d\n",capture_handle,&capture_handle,dev_name,samp_rate); if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) { fprintf (stderr, "cannot allocate hardware parameter structure (%s)\n", snd_strerror (err)); exit (1); } if ((err = snd_pcm_hw_params_any (capture_handle, hw_params)) < 0) { fprintf (stderr, "cannot initialize hardware parameter structure (%s)\n", snd_strerror (err)); exit (1); } if ((err = snd_pcm_hw_params_set_access (capture_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) { fprintf (stderr, "cannot set access type (%s)\n", snd_strerror(err)); exit (1); } if ((err = snd_pcm_hw_params_set_format (capture_handle, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) { fprintf (stderr, "cannot set sample format (%s)\n", snd_strerror (err)); exit (1); } if ((err = snd_pcm_hw_params_set_rate_resample(capture_handle,hw_params, 0)) < 0) { fprintf(stderr, "failed attempting to prevent ALSA resampling. (%s)", snd_strerror(err)); exit (1); } int dir = 0; unsigned int val = samp_rate; if ((err = snd_pcm_hw_params_set_rate_near (capture_handle, hw_params, &val, &dir)) < 0) { fprintf (stderr, "cannot set sample rate (%s)\n", snd_strerror (err)); exit (1); } if ((err = snd_pcm_hw_params_set_channels (capture_handle, hw_params, nchan)) < 0) { fprintf (stderr, "cannot set channel count (%s)\n", snd_strerror (err)); exit (1); } if ((err = snd_pcm_hw_params (capture_handle, hw_params)) < 0) { fprintf (stderr, "cannot set parameters (%s)\n", snd_strerror (err)); exit (1); } snd_pcm_hw_params_free (hw_params); if ((err = snd_pcm_prepare (capture_handle)) < 0) { fprintf (stderr, "cannot prepare audio interface for use (%s)\n", snd_strerror (err)); exit (1); } /* int nbuf = 8000; short *buf = (short*)malloc(sizeof(short)*nbuf); int i; for (i=0; i<2; ++i) { if ((err = snd_pcm_readi(capture_handle, buf, nbuf)) != nbuf) { fprintf (stderr, "read from audio interface failed (%s)\n", snd_strerror(err)); exit (1); } else { printf("read from C using %p into %p.\n",capture_handle,buf); } } */ }
bool PokeLaunchApplication::sound() { #if JUCE_LINUX int err; int freq = 44100, channels = 2; snd_pcm_hw_params_t *hw_params; snd_pcm_sw_params_t *sw_params; snd_pcm_hw_params_malloc( &hw_params ); snd_pcm_sw_params_malloc( &sw_params ); err = snd_pcm_open( &g_alsa_playback_handle, "default", SND_PCM_STREAM_PLAYBACK, 0 ); if( err < 0 ) { DBG( "ALSA ERROR: Can't open audio device: " << snd_strerror( err ) ); return false; } DBG("Opened Audio Device"); err = snd_pcm_hw_params_any( g_alsa_playback_handle, hw_params ); if( err < 0 ) { DBG( "ALSA ERROR: Can't initialize hardware parameter structure: " << snd_strerror( err ) ); return false; } err = snd_pcm_hw_params_set_access( g_alsa_playback_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED ); if( err < 0 ) { DBG( "ALSA ERROR: Can't set access type: " << snd_strerror( err ) ); return false; } //const UTF8_CHAR *sample_format = ""; err = snd_pcm_hw_params_set_format( g_alsa_playback_handle, hw_params, SND_PCM_FORMAT_S16_LE ); if( err < 0 ) { DBG( "ALSA ERROR: Can't set sample format :" << snd_strerror( err ) ); return false; } err = snd_pcm_hw_params_set_rate_near( g_alsa_playback_handle, hw_params, (unsigned int*)&freq, 0 ); if( err < 0 ) { DBG( "ALSA ERROR: Can't set sample rate: " << snd_strerror( err ) ); return false; } DBG( "ALSA Sample rate: "<< freq ); err = snd_pcm_hw_params_set_channels( g_alsa_playback_handle, hw_params, channels ); if( err < 0 ) { DBG( "ALSA ERROR: Can't set channel count: " << snd_strerror( err ) ); return false; } snd_pcm_uframes_t frames; frames = DEFAULT_BUFFER_SIZE; err = snd_pcm_hw_params_set_buffer_size_near( g_alsa_playback_handle, hw_params, &frames ); if( err < 0 ) { DBG( "ALSA ERROR: Can't set buffer size: " << snd_strerror( err ) ); return false; } snd_pcm_hw_params_get_buffer_size( hw_params, &frames ); DBG( "ALSA Buffer size: 4096 samples" ); err = snd_pcm_hw_params( g_alsa_playback_handle, hw_params ); if( err < 0 ) { DBG( "ALSA ERROR: Can't set parameters: " << snd_strerror( err ) ); return false; } snd_pcm_hw_params_free( hw_params ); snd_pcm_sw_params_free( sw_params ); err = snd_pcm_prepare( g_alsa_playback_handle ); if( err < 0 ) { DBG( "ALSA ERROR: Can't prepare audio interface for use: " << snd_strerror( err ) ); return false; } /* Stop PCM device and drop pending frames */ snd_pcm_drain(g_alsa_playback_handle); #endif return true; }
bool AlsaSound::AlsaInit() { unsigned int sample_rate = m_mixer->GetSampleRate(); int err; int dir; snd_pcm_sw_params_t *swparams; snd_pcm_hw_params_t *hwparams; snd_pcm_uframes_t buffer_size,buffer_size_max; unsigned int periods; err = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0); if (err < 0) { ERROR_LOG(AUDIO, "Audio open error: %s\n", snd_strerror(err)); return false; } snd_pcm_hw_params_alloca(&hwparams); err = snd_pcm_hw_params_any(handle, hwparams); if (err < 0) { ERROR_LOG(AUDIO, "Broken configuration for this PCM: %s\n", snd_strerror(err)); return false; } err = snd_pcm_hw_params_set_access(handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED); if (err < 0) { ERROR_LOG(AUDIO, "Access type not available: %s\n", snd_strerror(err)); return false; } err = snd_pcm_hw_params_set_format(handle, hwparams, SND_PCM_FORMAT_S16_LE); if (err < 0) { ERROR_LOG(AUDIO, "Sample format not available: %s\n", snd_strerror(err)); return false; } dir = 0; err = snd_pcm_hw_params_set_rate_near(handle, hwparams, &sample_rate, &dir); if (err < 0) { ERROR_LOG(AUDIO, "Rate not available: %s\n", snd_strerror(err)); return false; } err = snd_pcm_hw_params_set_channels(handle, hwparams, 2); if (err < 0) { ERROR_LOG(AUDIO, "Channels count not available: %s\n", snd_strerror(err)); return false; } periods = BUFFER_SIZE_MAX / FRAME_COUNT_MIN; err = snd_pcm_hw_params_set_periods_max(handle, hwparams, &periods, &dir); if (err < 0) { ERROR_LOG(AUDIO, "Cannot set Minimum periods: %s\n", snd_strerror(err)); return false; } buffer_size_max = BUFFER_SIZE_MAX; err = snd_pcm_hw_params_set_buffer_size_max(handle, hwparams, &buffer_size_max); if (err < 0) { ERROR_LOG(AUDIO, "Cannot set minimum buffer size: %s\n", snd_strerror(err)); return false; } err = snd_pcm_hw_params(handle, hwparams); if (err < 0) { ERROR_LOG(AUDIO, "Unable to install hw params: %s\n", snd_strerror(err)); return false; } err = snd_pcm_hw_params_get_buffer_size(hwparams, &buffer_size); if (err < 0) { ERROR_LOG(AUDIO, "Cannot get buffer size: %s\n", snd_strerror(err)); return false; } err = snd_pcm_hw_params_get_periods_max(hwparams, &periods, &dir); if (err < 0) { ERROR_LOG(AUDIO, "Cannot get periods: %s\n", snd_strerror(err)); return false; } //periods is the number of fragments alsa can wait for during one //buffer_size frames_to_deliver = buffer_size / periods; //limit the minimum size. pulseaudio advertises a minimum of 32 samples. if (frames_to_deliver < FRAME_COUNT_MIN) frames_to_deliver = FRAME_COUNT_MIN; //it is probably a bad idea to try to send more than one buffer of data if ((unsigned int)frames_to_deliver > buffer_size) frames_to_deliver = buffer_size; NOTICE_LOG(AUDIO, "ALSA gave us a %ld sample \"hardware\" buffer with %d periods. Will send %d samples per fragments.\n", buffer_size, periods, frames_to_deliver); snd_pcm_sw_params_alloca(&swparams); err = snd_pcm_sw_params_current(handle, swparams); if (err < 0) { ERROR_LOG(AUDIO, "cannot init sw params: %s\n", snd_strerror(err)); return false; } err = snd_pcm_sw_params_set_start_threshold(handle, swparams, 0U); if (err < 0) { ERROR_LOG(AUDIO, "cannot set start thresh: %s\n", snd_strerror(err)); return false; } err = snd_pcm_sw_params(handle, swparams); if (err < 0) { ERROR_LOG(AUDIO, "cannot set sw params: %s\n", snd_strerror(err)); return false; } err = snd_pcm_prepare(handle); if (err < 0) { ERROR_LOG(AUDIO, "Unable to prepare: %s\n", snd_strerror(err)); return false; } NOTICE_LOG(AUDIO, "ALSA successfully initialized.\n"); return true; }
void pcm_init() { int n, m, err; snd_pcm_hw_params_t *hw_params; if (!sound) { pcm.hz = 11025; pcm.len = 4096; pcm.buf = malloc(pcm.len); pcm.pos = 0; playback_handle = NULL; return; } if (!dsp_device) dsp_device = strdup(DSP_DEVICE); if ((err = snd_pcm_open (&playback_handle, dsp_device, SND_PCM_STREAM_PLAYBACK, 0)) < 0) { fprintf (stderr, "cannot open audio device %s (%s)\n", dsp_device, snd_strerror (err)); exit (1); } if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) { fprintf (stderr, "cannot allocate hardware parameter structure (%s)\n", snd_strerror (err)); exit (1); } if ((err = snd_pcm_hw_params_any (playback_handle, hw_params)) < 0) { fprintf (stderr, "cannot initialize hardware parameter structure (%s)\n", snd_strerror (err)); exit (1); } if ((err = snd_pcm_hw_params_set_access (playback_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) { fprintf (stderr, "cannot set access type (%s)\n", snd_strerror (err)); exit (1); } if ((err = snd_pcm_hw_params_set_format (playback_handle, hw_params, SND_PCM_FORMAT_U8)) < 0) { fprintf (stderr, "cannot set sample format (%s)\n", snd_strerror (err)); exit (1); } if ((err = snd_pcm_hw_params_set_rate_near (playback_handle, hw_params, samplerate, 0)) < 0) { fprintf (stderr, "cannot set sample rate (%s)\n", snd_strerror (err)); exit (1); } if ((err = snd_pcm_hw_params_set_channels (playback_handle, hw_params, stereo ? 2 : 1)) < 0) { fprintf (stderr, "cannot set channel count (%s)\n", snd_strerror (err)); exit (1); } if ((err = snd_pcm_hw_params (playback_handle, hw_params)) < 0) { fprintf (stderr, "cannot set parameters (%s)\n", snd_strerror (err)); exit (1); } snd_pcm_hw_params_free (hw_params); if ((err = snd_pcm_prepare (playback_handle)) < 0) { fprintf (stderr, "cannot prepare audio interface for use (%s)\n", snd_strerror (err)); exit (1); } pcm.stereo = stereo; pcm.hz = samplerate; pcm.len = 4096; pcm.buf = malloc(pcm.len); }
const VisPluginInfo *get_plugin_info (void) { static VisInputPlugin input = { .upload = inp_alsa_upload }; static VisPluginInfo info = { .type = VISUAL_PLUGIN_TYPE_INPUT, .plugname = "alsa", .name = "alsa", .author = "Vitaly V. Bursov <*****@*****.**>", .version = "0.1", .about = N_("ALSA capture plugin"), .help = N_("Use this plugin to capture PCM data from the ALSA record device"), .license = VISUAL_PLUGIN_LICENSE_LGPL, .init = inp_alsa_init, .cleanup = inp_alsa_cleanup, .plugin = &input }; return &info; } int inp_alsa_init (VisPluginData *plugin) { snd_pcm_hw_params_t *hwparams = NULL; alsaPrivate *priv; unsigned int rate = inp_alsa_var_samplerate; unsigned int exact_rate; unsigned int tmp; int dir = 0; int err; #if ENABLE_NLS bindtextdomain (GETTEXT_PACKAGE, LOCALE_DIR); #endif priv = visual_mem_new0 (alsaPrivate, 1); visual_plugin_set_private (plugin, priv); if ((err = snd_pcm_open(&priv->chandle, inp_alsa_var_cdevice, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK)) < 0) { visual_log(VISUAL_LOG_ERROR, "Record open error: %s", snd_strerror(err)); return FALSE; } snd_pcm_hw_params_malloc(&hwparams); visual_return_val_if_fail(hwparams != NULL, FALSE); if (snd_pcm_hw_params_any(priv->chandle, hwparams) < 0) { visual_log(VISUAL_LOG_ERROR, "Cannot configure this PCM device"); snd_pcm_hw_params_free(hwparams); return FALSE; } if (snd_pcm_hw_params_set_access(priv->chandle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED) < 0) { visual_log(VISUAL_LOG_ERROR, "Error setting access"); snd_pcm_hw_params_free(hwparams); return FALSE; } #if VISUAL_LITTLE_ENDIAN == 1 if (snd_pcm_hw_params_set_format(priv->chandle, hwparams, SND_PCM_FORMAT_S16_LE) < 0) { #else if (snd_pcm_hw_params_set_format(priv->chandle, hwparams, SND_PCM_FORMAT_S16_BE) < 0) { #endif visual_log(VISUAL_LOG_ERROR, "Error setting format"); snd_pcm_hw_params_free(hwparams); return FALSE; } exact_rate = rate; if (snd_pcm_hw_params_set_rate_near(priv->chandle, hwparams, &exact_rate, &dir) < 0) { visual_log(VISUAL_LOG_ERROR, "Error setting rate"); snd_pcm_hw_params_free(hwparams); return FALSE; } if (exact_rate != rate) { visual_log(VISUAL_LOG_INFO, "The rate %d Hz is not supported by your " \ "hardware.\n" \ "==> Using %d Hz instead", rate, exact_rate); } if (snd_pcm_hw_params_set_channels(priv->chandle, hwparams, inp_alsa_var_channels) < 0) { visual_log(VISUAL_LOG_ERROR, "Error setting channels"); snd_pcm_hw_params_free(hwparams); return FALSE; } /* Setup a large buffer */ tmp = 1000000; if (snd_pcm_hw_params_set_period_time_near(priv->chandle, hwparams, &tmp, &dir) < 0){ visual_log(VISUAL_LOG_ERROR, "Error setting period time"); snd_pcm_hw_params_free(hwparams); return FALSE; } tmp = 1000000*4; if (snd_pcm_hw_params_set_buffer_time_near(priv->chandle, hwparams, &tmp, &dir) < 0){ visual_log(VISUAL_LOG_ERROR, "Error setting buffer time"); snd_pcm_hw_params_free(hwparams); return FALSE; } if (snd_pcm_hw_params(priv->chandle, hwparams) < 0) { visual_log(VISUAL_LOG_ERROR, "Error setting HW params"); snd_pcm_hw_params_free(hwparams); return FALSE; } if (snd_pcm_prepare(priv->chandle) < 0) { visual_log(VISUAL_LOG_ERROR, "Failed to prepare interface"); snd_pcm_hw_params_free(hwparams); return FALSE; } snd_pcm_hw_params_free(hwparams); priv->loaded = TRUE; return TRUE; } void inp_alsa_cleanup (VisPluginData *plugin) { alsaPrivate *priv = visual_plugin_get_private (plugin); if (priv->loaded) { snd_pcm_close(priv->chandle); } visual_mem_free (priv); }
int listen_main(liqcell *liqmic_run) { long loops; int rc; int size; snd_pcm_t *handle; snd_pcm_hw_params_t *params; unsigned int val; int dir; snd_pcm_uframes_t frames; char *buffer; /* Open PCM device for recording (capture). */ rc = snd_pcm_open(&handle, "default", SND_PCM_STREAM_CAPTURE, 0); if (rc < 0) { fprintf(stderr, "unable to open pcm device: %s\n", snd_strerror(rc)); exit(1); } /* Allocate a hardware parameters object. */ snd_pcm_hw_params_alloca(¶ms); /* Fill it in with default values. */ snd_pcm_hw_params_any(handle, params); /* Set the desired hardware parameters. */ /* Interleaved mode */ snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); /* Signed 16-bit little-endian format */ snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE); /* Two channels (stereo) */ snd_pcm_hw_params_set_channels(handle, params, 1); /* 44100 bits/second sampling rate (CD quality) */ val = 44100; snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir); /* Set period size to 32 frames. */ frames = 32; snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir); /* Write the parameters to the driver */ rc = snd_pcm_hw_params(handle, params); if (rc < 0) { fprintf(stderr, "unable to set hw parameters: %s\n", snd_strerror(rc)); exit(1); } /* Use a buffer large enough to hold one period */ snd_pcm_hw_params_get_period_size(params, &frames, &dir); size = frames * 4; /* 2 bytes/sample, 2 channels */ buffer = (char *) malloc(size); /* We want to loop for 5 seconds */ snd_pcm_hw_params_get_period_time(params, &val, &dir); loops = 5000000 / val; while (loops > 0) { // loops--; rc = snd_pcm_readi(handle, buffer, frames); if (rc == -EPIPE) { /* EPIPE means overrun */ //fprintf(stderr, "overrun occurred\n"); snd_pcm_prepare(handle); } else if (rc < 0) { //fprintf(stderr, // "error from read: %s\n", // snd_strerror(rc)); } else if (rc != (int)frames) { //fprintf(stderr, "short read, read %d frames\n", rc); } filter((signed short *)buffer, size>>1,liqmic_run); //rc = write(1, buffer, size); //if (rc != size) // fprintf(stderr, // "short write: wrote %d bytes\n", rc); } snd_pcm_drain(handle); snd_pcm_close(handle); free(buffer); return 0; }
int main() { long loops; int rc,i = 0; int size; FILE *fp ; snd_pcm_t *handle; snd_pcm_hw_params_t *params; unsigned int val,val2; int dir; snd_pcm_uframes_t frames; char *buffer; if( (fp =fopen("sound.wav","w")) < 0) printf("open sound.wav fial\n"); /* Open PCM device for recording (capture). */ rc = snd_pcm_open(&handle, "default", SND_PCM_STREAM_CAPTURE, 0); if (rc < 0) { fprintf(stderr, "unable to open pcm device: %s/n", snd_strerror(rc)); exit(1); } /* Allocate a hardware parameters object. */ snd_pcm_hw_params_alloca(¶ms); /* Fill it in with default values. */ snd_pcm_hw_params_any(handle, params); /* Set the desired hardware parameters. */ /* Interleaved mode */ snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); /* Signed 16-bit little-endian format */ snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE); /* Two channels (stereo) */ snd_pcm_hw_params_set_channels(handle, params, 1); /* 44100 bits/second sampling rate (CD quality) */ val = 8000; snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir); /* Set period size to 32 frames. */ frames = 1024; snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir); /* Write the parameters to the driver */ rc = snd_pcm_hw_params(handle, params); if (rc < 0) { fprintf(stderr, "unable to set hw parameters: %s/n", snd_strerror(rc)); exit(1); } /* Use a buffer large enough to hold one period */ snd_pcm_hw_params_get_period_size(params, &frames, &dir); size = frames * 2; /* 2 bytes/sample, 2 channels */ printf("size = %d\n",size); buffer = (char *) malloc(size); /* We want to loop for 5 seconds */ snd_pcm_hw_params_get_period_time(params, &val, &dir); loops = 10000000 / val; while (loops > 0) { loops--; rc = snd_pcm_readi(handle, buffer, frames); printf("%d\n",i++); if (rc == -EPIPE) { /* EPIPE means overrun */ fprintf(stderr, "overrun occurred/n"); snd_pcm_prepare(handle); } else if (rc < 0) { fprintf(stderr, "error from read: %s/n", snd_strerror(rc)); } else if (rc != (int)frames) { fprintf(stderr, "short read, read %d frames/n", rc); } rc = fwrite( buffer,1, size,fp); // rc = write(1,buffer,size); if (rc != size) fprintf(stderr, "short write: wrote %d bytes/n", rc); else printf("fwrite buffer success\n"); } /*******************************************************************/ snd_pcm_drain(handle); snd_pcm_close(handle); fclose(fp); free(buffer); return 0; }
/** * Create and initialize Alsa audio output device with given parameters. * * @param Parameters - optional parameters * @throws AudioOutputException if output device cannot be opened */ AudioOutputDeviceAlsa::AudioOutputDeviceAlsa(std::map<String,DeviceCreationParameter*> Parameters) : AudioOutputDevice(Parameters), Thread(true, true, 1, 0) { pcm_handle = NULL; stream = SND_PCM_STREAM_PLAYBACK; this->uiAlsaChannels = ((DeviceCreationParameterInt*)Parameters["CHANNELS"])->ValueAsInt(); this->uiSamplerate = ((DeviceCreationParameterInt*)Parameters["SAMPLERATE"])->ValueAsInt(); this->FragmentSize = ((DeviceCreationParameterInt*)Parameters["FRAGMENTSIZE"])->ValueAsInt(); uint Fragments = ((DeviceCreationParameterInt*)Parameters["FRAGMENTS"])->ValueAsInt(); String Card = ((DeviceCreationParameterString*)Parameters["CARD"])->ValueAsString(); dmsg(2,("Checking if hw parameters supported...\n")); if (HardwareParametersSupported(Card, uiAlsaChannels, uiSamplerate, Fragments, FragmentSize)) { pcm_name = "hw:" + Card; } else { fprintf(stderr, "Warning: your soundcard doesn't support chosen hardware parameters; "); fprintf(stderr, "trying to compensate support lack with plughw..."); fflush(stdout); pcm_name = "plughw:" + Card; } dmsg(2,("HW check completed.\n")); int err; snd_pcm_hw_params_alloca(&hwparams); // Allocate the snd_pcm_hw_params_t structure on the stack. /* Open PCM. The last parameter of this function is the mode. */ /* If this is set to 0, the standard mode is used. Possible */ /* other values are SND_PCM_NONBLOCK and SND_PCM_ASYNC. */ /* If SND_PCM_NONBLOCK is used, read / write access to the */ /* PCM device will return immediately. If SND_PCM_ASYNC is */ /* specified, SIGIO will be emitted whenever a period has */ /* been completely processed by the soundcard. */ if ((err = snd_pcm_open(&pcm_handle, pcm_name.c_str(), stream, 0)) < 0) { throw AudioOutputException(String("Error opening PCM device ") + pcm_name + ": " + snd_strerror(err)); } if ((err = snd_pcm_hw_params_any(pcm_handle, hwparams)) < 0) { throw AudioOutputException(String("Error, cannot initialize hardware parameter structure: ") + snd_strerror(err)); } /* Set access type. This can be either */ /* SND_PCM_ACCESS_RW_INTERLEAVED or */ /* SND_PCM_ACCESS_RW_NONINTERLEAVED. */ if ((err = snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) { throw AudioOutputException(String("Error snd_pcm_hw_params_set_access: ") + snd_strerror(err)); } /* Set sample format */ #if WORDS_BIGENDIAN if ((err = snd_pcm_hw_params_set_format(pcm_handle, hwparams, SND_PCM_FORMAT_S16_BE)) < 0) #else // little endian if ((err = snd_pcm_hw_params_set_format(pcm_handle, hwparams, SND_PCM_FORMAT_S16_LE)) < 0) #endif { throw AudioOutputException(String("Error setting sample format: ") + snd_strerror(err)); } int dir = 0; /* Set sample rate. If the exact rate is not supported */ /* by the hardware, use nearest possible rate. */ #if ALSA_MAJOR > 0 if((err = snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &uiSamplerate, &dir)) < 0) #else if((err = snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, uiSamplerate, &dir)) < 0) #endif { throw AudioOutputException(String("Error setting sample rate: ") + snd_strerror(err)); } if ((err = snd_pcm_hw_params_set_channels(pcm_handle, hwparams, uiAlsaChannels)) < 0) { throw AudioOutputException(String("Error setting number of channels: ") + snd_strerror(err)); } /* Set number of periods. Periods used to be called fragments. */ if ((err = snd_pcm_hw_params_set_periods(pcm_handle, hwparams, Fragments, dir)) < 0) { throw AudioOutputException(String("Error setting number of ") + ToString(Fragments) + " periods: " + snd_strerror(err)); } /* Set buffer size (in frames). The resulting latency is given by */ /* latency = periodsize * periods / (rate * bytes_per_frame) */ if ((err = snd_pcm_hw_params_set_buffer_size(pcm_handle, hwparams, (FragmentSize * Fragments))) < 0) { throw AudioOutputException(String("Error setting buffersize: ") + snd_strerror(err)); } /* Apply HW parameter settings to */ /* PCM device and prepare device */ if ((err = snd_pcm_hw_params(pcm_handle, hwparams)) < 0) { throw AudioOutputException(String("Error setting HW params: ") + snd_strerror(err)); } if (snd_pcm_sw_params_malloc(&swparams) != 0) { throw AudioOutputException(String("Error in snd_pcm_sw_params_malloc: ") + snd_strerror(err)); } if (snd_pcm_sw_params_current(pcm_handle, swparams) != 0) { throw AudioOutputException(String("Error in snd_pcm_sw_params_current: ") + snd_strerror(err)); } if (snd_pcm_sw_params_set_stop_threshold(pcm_handle, swparams, 0xffffffff) != 0) { throw AudioOutputException(String("Error in snd_pcm_sw_params_set_stop_threshold: ") + snd_strerror(err)); } if (snd_pcm_sw_params(pcm_handle, swparams) != 0) { throw AudioOutputException(String("Error in snd_pcm_sw_params: ") + snd_strerror(err)); } if ((err = snd_pcm_prepare(pcm_handle)) < 0) { throw AudioOutputException(String("Error snd_pcm_prepare: ") + snd_strerror(err)); } // allocate Alsa output buffer pAlsaOutputBuffer = new int16_t[uiAlsaChannels * FragmentSize]; // create audio channels for this audio device to which the sampler engines can write to for (int i = 0; i < uiAlsaChannels; i++) this->Channels.push_back(new AudioChannel(i, FragmentSize)); if (((DeviceCreationParameterBool*)Parameters["ACTIVE"])->ValueAsBool()) { Play(); } }
/* public methods (static but exported through the sysdep_dsp or plugin struct) */ static void *alsa_dsp_create(const void *flags) { int i, j; // audio_buf_info info; struct alsa_dsp_priv_data *priv = NULL; struct sysdep_dsp_struct *dsp = NULL; const struct sysdep_dsp_create_params *params = flags; const char *device = params->device; int err; int bytespersample; fprintf(stderr,"info: dsp_create called\n"); /* allocate the dsp struct */ if (!(dsp = calloc(1, sizeof(struct sysdep_dsp_struct)))) { fprintf(stderr, "error: malloc failed for struct sysdep_dsp_struct\n"); return NULL; } /* alloc private data */ if(!(priv = calloc(1, sizeof(struct alsa_dsp_priv_data)))) { fprintf(stderr, "error: malloc failed for struct dsp_priv_data\n"); alsa_dsp_destroy(dsp); return NULL; } /* fill in the functions and some data */ dsp->_priv = priv; dsp->get_freespace = alsa_dsp_get_freespace; dsp->write = alsa_dsp_write; dsp->destroy = alsa_dsp_destroy; dsp->hw_info.type = params->type; dsp->hw_info.samplerate = params->samplerate; priv->audio_dev.bMute = 0; priv->audio_dev.m_AudioHandle = NULL; priv->audio_dev.m_MixerHandle = NULL; priv->audio_dev.m_Acard = 0; priv->audio_dev.m_Adevice = 0; if (preferred_device) { if((err = snd_pcm_open_preferred(&(priv->audio_dev.m_AudioHandle), &priv->audio_dev.m_Acard, &priv->audio_dev.m_Adevice, SND_PCM_OPEN_PLAYBACK)) < 0) { fprintf(stderr,"info: snd_pcm_open_preferred failed: %s \n", snd_strerror(err)); alsa_dsp_destroy(dsp); return NULL; } } else { fprintf(stderr,"info: audio is using primary device\n"); if((err = snd_pcm_open(&(priv->audio_dev.m_AudioHandle), 0, 0, SND_PCM_OPEN_PLAYBACK)) < 0) { fprintf(stderr,"info: snd_pcm_open failed: %s \n", snd_strerror(err)); alsa_dsp_destroy(dsp); return NULL; } } memset (&(priv->audio_dev.m_Achaninfo), 0, sizeof (priv->audio_dev.m_Achaninfo)); priv->audio_dev.m_Achaninfo.channel = SND_PCM_CHANNEL_PLAYBACK; if ((err = snd_pcm_plugin_info (priv->audio_dev.m_AudioHandle, &(priv->audio_dev.m_Achaninfo))) < 0) { fprintf (stderr, "info: snd_pcm_plugin_info failed: %s\n", snd_strerror (err)); alsa_dsp_destroy(dsp); return NULL; } //needed to enable the count status parameter, mmap plugin disables this if((err = snd_plugin_set_disable(priv->audio_dev.m_AudioHandle, PLUGIN_DISABLE_MMAP)) < 0) { fprintf (stderr, "info: snd_plugin_set_disable failed: %s\n", snd_strerror (err)); alsa_dsp_destroy(dsp); return NULL; } /* calculate and set the fragsize & number of frags */ /* fragsize (as power of 2) */ i = 8; if (dsp->hw_info.type & SYSDEP_DSP_16BIT) i++; if (dsp->hw_info.type & SYSDEP_DSP_STEREO) i++; i += dsp->hw_info.samplerate / 22000; /* number of frags */ j = ((dsp->hw_info.samplerate * alsa_dsp_bytes_per_sample[dsp->hw_info.type] * params->bufsize) / (0x01 << i)) + 1; bytespersample=1; // dsp->hw_info.type &= ~SYSDEP_DSP_16BIT; // dsp->hw_info.type &= ~SYSDEP_DSP_STEREO; if (dsp->hw_info.type & SYSDEP_DSP_16BIT) bytespersample++; if (dsp->hw_info.type & SYSDEP_DSP_STEREO) bytespersample <<= 1; memset( &(priv->audio_dev.m_Aparams), 0, sizeof(priv->audio_dev.m_Aparams)); priv->audio_dev.m_Aparams.mode = SND_PCM_MODE_BLOCK; priv->audio_dev.m_Aparams.channel = SND_PCM_CHANNEL_PLAYBACK; priv->audio_dev.m_Aparams.start_mode = SND_PCM_START_FULL; priv->audio_dev.m_Aparams.stop_mode = SND_PCM_STOP_ROLLOVER; #if 0 priv->audio_dev.m_Aparams.buf.stream.queue_size = 512 * bytespersample; priv->audio_dev.m_Aparams.buf.stream.fill = SND_PCM_FILL_SILENCE; priv->audio_dev.m_Aparams.buf.stream.max_fill = 512 * bytespersample; #endif priv->audio_dev.m_Aparams.format.interleave = 1; priv->audio_dev.m_Aparams.format.rate = dsp->hw_info.samplerate; priv->audio_dev.m_Aparams.format.voices = (dsp->hw_info.type & SYSDEP_DSP_STEREO) ? 2 : 1; priv->audio_dev.m_Aparams.buf.block.frag_size = 1000; priv->audio_dev.m_Aparams.buf.block.frags_min = 1; priv->audio_dev.m_Aparams.buf.block.frags_max = 5; priv->audio_dev.m_BytesPerSample = bytespersample; priv->audio_dev.m_Aparams.format.format = #ifdef LSB_FIRST (dsp->hw_info.type & SYSDEP_DSP_16BIT) ? SND_PCM_SFMT_S16_LE : SND_PCM_SFMT_U8; #else (dsp->hw_info.type & SYSDEP_DSP_16BIT) ? SND_PCM_SFMT_S16_BE : SND_PCM_SFMT_U8; #endif if ((err = snd_pcm_plugin_params (priv->audio_dev.m_AudioHandle, &(priv->audio_dev.m_Aparams))) < 0) { fprintf (stderr, "info: snd_pcm_plugin_params failed: %s\n", snd_strerror (err)); alsa_dsp_destroy(dsp); return NULL; } if ((err = snd_pcm_plugin_prepare (priv->audio_dev.m_AudioHandle, SND_PCM_CHANNEL_PLAYBACK)) < 0) { fprintf (stderr, "warning: snd_pcm_plugin_prepare failed: %s\n", snd_strerror (err)); } memset (&(priv->audio_dev.m_Asetup), 0, sizeof (priv->audio_dev.m_Asetup)); priv->audio_dev.m_Asetup.channel = SND_PCM_CHANNEL_PLAYBACK; if ((err = snd_pcm_plugin_setup (priv->audio_dev.m_AudioHandle, &(priv->audio_dev.m_Asetup))) < 0) { fprintf (stderr, "warning: snd_pcm_plugin_setup failed: %s\n", snd_strerror (err)); alsa_dsp_destroy(dsp); return NULL; } memset (&(priv->audio_dev.m_Astatus), 0, sizeof (priv->audio_dev.m_Astatus)); priv->audio_dev.m_Astatus.channel = SND_PCM_CHANNEL_PLAYBACK; if ((err = snd_pcm_plugin_status (priv->audio_dev.m_AudioHandle, &(priv->audio_dev.m_Astatus))) < 0) { fprintf (stderr, "warning: snd_pcm_plugin_status failed: %s\n", snd_strerror (err)); } dsp->hw_info.bufsize = priv->audio_dev.m_Asetup.buf.stream.queue_size / alsa_dsp_bytes_per_sample[dsp->hw_info.type]; #if 0 if ((err=snd_pcm_nonblock_mode(priv->audio_dev.m_AudioHandle, 1))<0) { fprintf(stderr, "error: error with non block mode: %s\n", snd_strerror (err)); } #endif return dsp; }
int audio_alsa_init() { int fd, err; char *pcm_rate; char tmp_name[20]; init_rec_buffer(); /* Create a temporary filename for our FIFO, * Use mkstemp() instead of mktemp() although we need a FIFO not a * regular file. We do this since glibc barfs at mktemp() and this * scares the users :-) */ strcpy(tmp_name, "/tmp/lircXXXXXX"); fd = mkstemp(tmp_name); close(fd); /* Start the race! */ unlink(tmp_name); if (mknod(tmp_name, S_IFIFO | S_IRUSR | S_IWUSR, 0)) { logprintf(LOG_ERR, "could not create FIFO %s", tmp_name); logperror(LOG_ERR, "audio_alsa_init ()"); return 0; } /* Phew, we won the race ... */ /* Open the pipe and hand it to LIRC ... */ hw.fd = open(tmp_name, O_RDWR); if (hw.fd < 0) { logprintf(LOG_ERR, "could not open pipe %s", tmp_name); logperror(LOG_ERR, "audio_alsa_init ()"); error: unlink(tmp_name); audio_alsa_deinit(); return 0; } /* Open the other end of the pipe and hand it to ALSA code. * We're opening it in non-blocking mode to avoid lockups. */ alsa_hw.fd = open(tmp_name, O_RDWR | O_NONBLOCK); /* Ok, we don't need the FIFO visible in the filesystem anymore ... */ unlink(tmp_name); /* Examine the device name, if it contains a sample rate */ strncpy(tmp_name, hw.device, sizeof(tmp_name) - 1); pcm_rate = strchr(tmp_name, '@'); if (pcm_rate) { int rate; char *stereo_channel; /* Examine if we need to capture in stereo * looking for an 'l' or 'r' character to indicate * which channel to look at.*/ stereo_channel = strchr(pcm_rate, ','); if (stereo_channel) { /* Syntax in device string indicates we need to use stereo */ alsa_hw.num_channels = 2; /* As we are requesting stereo now, use the more common signed 16bit samples */ alsa_hw.format = SND_PCM_FORMAT_S16_LE; if (stereo_channel[1] == 'l') { alsa_hw.channel = 0; } else if (stereo_channel[1] == 'r') { alsa_hw.channel = 1; } else { logperror(LOG_WARNING, "dont understand which channel to use - defaulting to left\n"); } } /* Remove the sample rate from device name (and channel indicator if present) */ *pcm_rate++ = 0; /* See if rate is meaningful */ rate = atoi(pcm_rate); if (rate > 0) { alsa_hw.rate = rate; } } /* Open the audio card in non-blocking mode */ err = snd_pcm_open(&alsa_hw.handle, tmp_name, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK); if (err < 0) { logprintf(LOG_ERR, "could not open audio device %s: %s", hw.device, snd_strerror(err)); logperror(LOG_ERR, "audio_alsa_init ()"); goto error; } /* Set up the I/O signal handler */ if (alsa_error ("async_add_handler", snd_async_add_pcm_handler(&alsa_hw.sighandler, alsa_hw.handle, alsa_sig_io, NULL))) goto error; /* Set sampling parameters */ if (alsa_set_hwparams(alsa_hw.handle)) goto error; LOGPRINTF(LOG_INFO, "hw_audio_alsa: Using device '%s', sampling rate %dHz\n", tmp_name, alsa_hw.rate); /* Start sampling data */ if (alsa_error("start", snd_pcm_start(alsa_hw.handle))) goto error; return 1; }
int main(int argc, char **argv) { char *device = NULL; int stream = SND_PCM_STREAM_PLAYBACK; int format = SND_PCM_FORMAT_UNKNOWN; int channels = 0; int rate = 0; snd_pcm_t *pcm; int c; while ((c = getopt(argc, argv, "D:s:f:c:r:")) != -1) { switch (c) { case 'D': device = optarg; break; case 's': if (*optarg == 'c' || *optarg == 'C') stream = SND_PCM_STREAM_CAPTURE; else stream = SND_PCM_STREAM_PLAYBACK; break; case 'f': format = snd_pcm_format_value(optarg); break; case 'c': channels = atoi(optarg); break; case 'r': rate = atoi(optarg); break; default: usage(); return 1; } } if (argc <= optind) { usage(); return 1; } if (!device) { printf("No device is specified\n"); return 1; } if (snd_pcm_open(&pcm, device, stream, SND_PCM_NONBLOCK) < 0) { printf("Cannot open PCM stream %s for %s\n", device, snd_pcm_stream_name(stream)); return 1; } switch (*argv[optind]) { case 'q': return query_chmaps(pcm); case 'g': return get_chmap(pcm, format, channels, rate); case 's': return set_chmap(pcm, format, channels, rate, argc - optind - 1, argv + optind + 1); } usage(); return 1; }
bool CALSAAudioSource::InitDevice(void) { int err; // Capture stream snd_pcm_stream_t stream = SND_PCM_STREAM_CAPTURE; // This structure contains information about // the hardware and can be used to specify the // configuration to be used for the PCM stream. snd_pcm_hw_params_t *hwparams; // Name of the PCM device, like plughw:0,0 const char *pcm_name = m_pConfig->GetStringValue(CONFIG_AUDIO_SOURCE_NAME); // Allocate the snd_pcm_hw_params_t structure on the stack. snd_pcm_hw_params_alloca(&hwparams); // Open PCM if ((err = snd_pcm_open(&m_pcmHandle, pcm_name, stream, 0)) < 0) { error_message("Failed to open %s: %s", pcm_name, snd_strerror(err)); return false; } // Init hwparams with full configuration space if ((err = snd_pcm_hw_params_any(m_pcmHandle, hwparams)) < 0) { error_message("Can not configure the PCM device %s: %s", pcm_name, snd_strerror(err)); return false; } // Enable resample #ifdef HAVE_SND_PCM_HW_PARAMS_SET_RATE_RESAMPLE if ((err = snd_pcm_hw_params_set_rate_resample(m_pcmHandle, hwparams, 1)) < 0) { error_message("Error enabling resample for PCM device %s: %s", pcm_name, snd_strerror(err)); return false; } #endif // Set access type to SND_PCM_ACCESS_RW_INTERLEAVED if ((err = snd_pcm_hw_params_set_access(m_pcmHandle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) { error_message("Error setting access type for PCM device %s: %s", pcm_name, snd_strerror(err)); return false; } // Set sample format #ifdef WORDS_BIGENDIAN #define OUR_FORMAT SND_PCM_FORMAT_S16_BE #else #define OUR_FORMAT SND_PCM_FORMAT_S16_LE #endif if ((err = snd_pcm_hw_params_set_format(m_pcmHandle, hwparams, OUR_FORMAT)) < 0) { error_message("Couldn't set format for PCM device %s: %s", pcm_name, snd_strerror(err)); snd_pcm_close(m_pcmHandle); return false; } // Set number of channels m_channelsConfigured = m_pConfig->GetIntegerValue(CONFIG_AUDIO_CHANNELS); if ((err = snd_pcm_hw_params_set_channels(m_pcmHandle, hwparams, m_channelsConfigured)) < 0) { error_message("Couldn't set audio channels for PCM device %s: %s", pcm_name, snd_strerror(err)); snd_pcm_close(m_pcmHandle); return false; } // Set sample rate u_int32_t samplingRate = m_pConfig->GetIntegerValue(CONFIG_AUDIO_SAMPLE_RATE); u_int32_t targetSamplingRate = samplingRate; // TODO maybe use snd_pcm_hw_params_set_rate instead if ((err = snd_pcm_hw_params_set_rate_near(m_pcmHandle, hwparams, &targetSamplingRate, 0)) < 0) { error_message("Couldn't set sample rate for PCM device %s: %s", pcm_name, snd_strerror(err)); snd_pcm_close(m_pcmHandle); return false; } if (samplingRate != targetSamplingRate) { error_message("Couldn't set sample rate for PCM device %s", pcm_name); snd_pcm_close(m_pcmHandle); return false; } // Apply HW parameter settings to PCM device. This will also put it into PREPARED state if ((err = snd_pcm_hw_params(m_pcmHandle, hwparams)) < 0) { error_message("Couldn't set hw parameters PCM device %s: %s", pcm_name, snd_strerror(err)); snd_pcm_close(m_pcmHandle); return false; } debug_message("alsa init done"); return true; }