int set_hwparams(snd_pcm_t *handle, snd_pcm_hw_params_t *params, snd_pcm_access_t access) { unsigned int rrate; int err, dir; printf("set_hwparams\n"); /* choose all parameters */ err = snd_pcm_hw_params_any(handle, params); if (err < 0) { printf("Broken configuration for playback: no configurations available: %s\n", snd_strerror(err)); return err; } /* set the interleaved read/write format */ err = snd_pcm_hw_params_set_access(handle, params, access); if (err < 0) { printf("Access type not available for playback: %s\n", snd_strerror(err)); return err; } /* set the sample format */ err = snd_pcm_hw_params_set_format(handle, params, format); if (err < 0) { printf("Sample format not available for playback: %s\n", snd_strerror(err)); return err; } /* set the count of channels */ err = snd_pcm_hw_params_set_channels(handle, params, channels); if (err < 0) { printf("Channels count (%i) not available for playbacks: %s\n", channels, snd_strerror(err)); return err; } /* set the stream rate */ rrate = rate; err = snd_pcm_hw_params_set_rate_near(handle, params, &rrate, 0); if (err < 0) { printf("Rate %iHz not available for playback: %s\n", rate, snd_strerror(err)); return err; } if (rrate != rate) { printf("Rate doesn't match (requested %iHz, get %iHz)\n", rate, err); return -EINVAL; } dir = 0; err = snd_pcm_hw_params_set_period_size_near(handle, params, &period_size, &dir); if (err < 0) { printf("Unable to set period size %i for playback: %s\n", (int)period_size, snd_strerror(err)); return err; } err = snd_pcm_hw_params_set_periods(handle, params, periods, 0); if (err < 0) { printf("Unable to set periods %i for playback: %s\n", periods, snd_strerror(err)); return err; } /* write the parameters to device */ err = snd_pcm_hw_params(handle, params); if (err < 0) { printf("Unable to set hw params for playback: %s\n", snd_strerror(err)); return err; } err = snd_pcm_hw_params_get_periods(params, &periods, &dir); if (err < 0) { printf("Unable to get periods for playback: %s\n", snd_strerror(err)); return err; } err = snd_pcm_hw_params_get_period_size(params, &period_size, &dir); if (err < 0) { printf("Unable to get period size for playback: %s\n", snd_strerror(err)); return err; } return 0; }
int pcm_open_set_device() { int rc; snd_pcm_t *handle; snd_pcm_hw_params_t *params; snd_pcm_format_t val3; unsigned int val, val2; int dir; snd_pcm_uframes_t frames; /* Open PCM device for playback. */ //plughw:U0x46d0x825,0 //hw:1,0 rc = snd_pcm_open(&handle, "plughw:1,0", SND_PCM_STREAM_PLAYBACK, 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_NONINTERLEAVED); /* 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); /* 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); } /* Display information about the PCM interface */ printf("PCM handle name = '%s'\n", snd_pcm_name(handle)); printf("PCM state = %s\n", snd_pcm_state_name(snd_pcm_state(handle))); snd_pcm_hw_params_get_access(params, (snd_pcm_access_t *) & val); printf("access type = %s\n", snd_pcm_access_name((snd_pcm_access_t) val)); snd_pcm_hw_params_get_format(params, (snd_pcm_format_t*) & val); printf("format = '%s' (%s)\n", snd_pcm_format_name((snd_pcm_format_t) val), snd_pcm_format_description((snd_pcm_format_t) val)); snd_pcm_hw_params_get_subformat(params, (snd_pcm_subformat_t *) & val); printf("subformat = '%s' (%s)\n", snd_pcm_subformat_name((snd_pcm_subformat_t) val), snd_pcm_subformat_description((snd_pcm_subformat_t) val)); 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 sps\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_close(handle); return 0; }
void* DAUDIO_Open(INT32 mixerIndex, INT32 deviceID, int isSource, int encoding, float sampleRate, int sampleSizeInBits, int frameSize, int channels, int isSigned, int isBigEndian, int bufferSizeInBytes) { snd_pcm_format_mask_t* formatMask; snd_pcm_format_t format; int dir; int ret = 0; AlsaPcmInfo* info = NULL; /* snd_pcm_uframes_t is 64 bit on 64-bit systems */ snd_pcm_uframes_t alsaPeriodSize = 0; snd_pcm_uframes_t alsaBufferSizeInFrames = 0; TRACE0("> DAUDIO_Open\n"); #ifdef USE_TRACE // for using ALSA debug dump methods if (ALSA_OUTPUT == NULL) { snd_output_stdio_attach(&ALSA_OUTPUT, stdout, 0); } #endif info = (AlsaPcmInfo*) malloc(sizeof(AlsaPcmInfo)); if (!info) { ERROR0("Out of memory\n"); return NULL; } memset(info, 0, sizeof(AlsaPcmInfo)); ret = openPCMfromDeviceID(deviceID, &(info->handle), isSource, FALSE /* do open device*/); if (ret == 0) { // set to blocking mode snd_pcm_nonblock(info->handle, 0); ret = snd_pcm_hw_params_malloc(&(info->hwParams)); if (ret != 0) { ERROR1(" snd_pcm_hw_params_malloc returned error %d\n", ret); } else { ret = -1; if (getAlsaFormatFromFormat(&format, frameSize / channels, sampleSizeInBits, isSigned, isBigEndian, encoding)) { if (setHWParams(info, sampleRate, channels, bufferSizeInBytes / frameSize, format)) { info->frameSize = frameSize; #ifdef ALSA_PCM_NEW_HW_PARAMS_API ret = snd_pcm_hw_params_get_period_size(info->hwParams, &alsaPeriodSize, &dir); info->periodSize = (int) alsaPeriodSize; if (ret < 0) { ERROR1("ERROR: snd_pcm_hw_params_get_period: %s\n", snd_strerror(ret)); } snd_pcm_hw_params_get_periods(info->hwParams, &(info->periods), &dir); snd_pcm_hw_params_get_buffer_size(info->hwParams, &alsaBufferSizeInFrames); info->bufferSizeInBytes = (int) alsaBufferSizeInFrames * frameSize; #else info->periodSize = snd_pcm_hw_params_get_period_size(info->hwParams, &dir); info->periods = snd_pcm_hw_params_get_periods(info->hwParams, &dir); info->bufferSizeInBytes = snd_pcm_hw_params_get_buffer_size(info->hwParams) * frameSize; ret = 0; #endif TRACE3(" DAUDIO_Open: period size = %d frames, periods = %d. Buffer size: %d bytes.\n", (int) info->periodSize, info->periods, info->bufferSizeInBytes); } } } if (ret == 0) { // set software parameters ret = snd_pcm_sw_params_malloc(&(info->swParams)); if (ret != 0) { ERROR1("snd_pcm_hw_params_malloc returned error %d\n", ret); } else { if (!setSWParams(info)) { ret = -1; } } } if (ret == 0) { // prepare device ret = snd_pcm_prepare(info->handle); if (ret < 0) { ERROR1("ERROR: snd_pcm_prepare: %s\n", snd_strerror(ret)); } } #ifdef GET_POSITION_METHOD2 if (ret == 0) { ret = snd_pcm_status_malloc(&(info->positionStatus)); if (ret != 0) { ERROR1("ERROR in snd_pcm_status_malloc: %s\n", snd_strerror(ret)); } } #endif } if (ret != 0) { DAUDIO_Close((void*) info, isSource); info = NULL; } else { // set to non-blocking mode snd_pcm_nonblock(info->handle, 1); TRACE1("< DAUDIO_Open: Opened device successfully. Handle=%p\n", (void*) info->handle); } return (void*) info; }
bool setParameters (unsigned int sampleRate, int numChannels, int bufferSize) { if (handle == 0) return false; snd_pcm_hw_params_t* hwParams; snd_pcm_hw_params_alloca (&hwParams); if (failed (snd_pcm_hw_params_any (handle, hwParams))) return false; if (snd_pcm_hw_params_set_access (handle, hwParams, SND_PCM_ACCESS_RW_NONINTERLEAVED) >= 0) isInterleaved = false; else if (snd_pcm_hw_params_set_access (handle, hwParams, SND_PCM_ACCESS_RW_INTERLEAVED) >= 0) isInterleaved = true; else { jassertfalse; return false; } enum { isFloatBit = 1 << 16, isLittleEndianBit = 1 << 17 }; const int formatsToTry[] = { SND_PCM_FORMAT_FLOAT_LE, 32 | isFloatBit | isLittleEndianBit, SND_PCM_FORMAT_FLOAT_BE, 32 | isFloatBit, SND_PCM_FORMAT_S32_LE, 32 | isLittleEndianBit, SND_PCM_FORMAT_S32_BE, 32, SND_PCM_FORMAT_S24_3LE, 24 | isLittleEndianBit, SND_PCM_FORMAT_S24_3BE, 24, SND_PCM_FORMAT_S16_LE, 16 | isLittleEndianBit, SND_PCM_FORMAT_S16_BE, 16 }; bitDepth = 0; for (int i = 0; i < numElementsInArray (formatsToTry); i += 2) { if (snd_pcm_hw_params_set_format (handle, hwParams, (_snd_pcm_format) formatsToTry [i]) >= 0) { bitDepth = formatsToTry [i + 1] & 255; const bool isFloat = (formatsToTry [i + 1] & isFloatBit) != 0; const bool isLittleEndian = (formatsToTry [i + 1] & isLittleEndianBit) != 0; converter = createConverter (isInput, bitDepth, isFloat, isLittleEndian, numChannels); break; } } if (bitDepth == 0) { error = "device doesn't support a compatible PCM format"; DBG ("ALSA error: " + error + "\n"); return false; } int dir = 0; unsigned int periods = 4; snd_pcm_uframes_t samplesPerPeriod = bufferSize; if (failed (snd_pcm_hw_params_set_rate_near (handle, hwParams, &sampleRate, 0)) || failed (snd_pcm_hw_params_set_channels (handle, hwParams, numChannels)) || failed (snd_pcm_hw_params_set_periods_near (handle, hwParams, &periods, &dir)) || failed (snd_pcm_hw_params_set_period_size_near (handle, hwParams, &samplesPerPeriod, &dir)) || failed (snd_pcm_hw_params (handle, hwParams))) { return false; } snd_pcm_uframes_t frames = 0; if (failed (snd_pcm_hw_params_get_period_size (hwParams, &frames, &dir)) || failed (snd_pcm_hw_params_get_periods (hwParams, &periods, &dir))) latency = 0; else latency = frames * (periods - 1); // (this is the method JACK uses to guess the latency..) snd_pcm_sw_params_t* swParams; snd_pcm_sw_params_alloca (&swParams); snd_pcm_uframes_t boundary; if (failed (snd_pcm_sw_params_current (handle, swParams)) || failed (snd_pcm_sw_params_get_boundary (swParams, &boundary)) || failed (snd_pcm_sw_params_set_silence_threshold (handle, swParams, 0)) || failed (snd_pcm_sw_params_set_silence_size (handle, swParams, boundary)) || failed (snd_pcm_sw_params_set_start_threshold (handle, swParams, samplesPerPeriod)) || failed (snd_pcm_sw_params_set_stop_threshold (handle, swParams, boundary)) || failed (snd_pcm_sw_params (handle, swParams))) { return false; } #if 0 // enable this to dump the config of the devices that get opened snd_output_t* out; snd_output_stdio_attach (&out, stderr, 0); snd_pcm_hw_params_dump (hwParams, out); snd_pcm_sw_params_dump (swParams, out); #endif numChannelsRunning = numChannels; return true; }
/* alsa_init: * ALSA init routine. */ static int alsa_init(int input, int voices) { int ret = 0; char tmp1[128], tmp2[128]; int format = 0; unsigned int numfrags = 0; snd_pcm_uframes_t fragsize; if (input) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Input is not supported")); return -1; } ALSA9_CHECK(snd_output_stdio_attach(&snd_output, stdout, 0)); alsa_device = get_config_string(uconvert_ascii("sound", tmp1), uconvert_ascii("alsa_device", tmp2), alsa_device); alsa_mixer_device = get_config_string(uconvert_ascii("sound", tmp1), uconvert_ascii("alsa_mixer_device", tmp2), alsa_mixer_device); fragsize = get_config_int(uconvert_ascii("sound", tmp1), uconvert_ascii("alsa_fragsize", tmp2), 0); numfrags = get_config_int(uconvert_ascii("sound", tmp1), uconvert_ascii("alsa_numfrags", tmp2), ALSA_DEFAULT_NUMFRAGS); ret = snd_pcm_open(&pcm_handle, alsa_device, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); if (ret < 0) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not open card/pcm device")); return -1; } snd_mixer_open(&alsa_mixer, 0); if (alsa_mixer && snd_mixer_attach(alsa_mixer, alsa_mixer_device) >= 0 && snd_mixer_selem_register (alsa_mixer, NULL, NULL) >= 0 && snd_mixer_load(alsa_mixer) >= 0) { const char *alsa_mixer_elem_name = get_config_string(uconvert_ascii("sound", tmp1), uconvert_ascii("alsa_mixer_elem", tmp2), "PCM"); alsa_mixer_elem = snd_mixer_first_elem(alsa_mixer); while (alsa_mixer_elem) { const char *name = snd_mixer_selem_get_name(alsa_mixer_elem); if (strcasecmp(name, alsa_mixer_elem_name) == 0) { snd_mixer_selem_get_playback_volume_range(alsa_mixer_elem, &alsa_mixer_elem_min, &alsa_mixer_elem_max); alsa_mixer_allegro_ratio = (double) (alsa_mixer_elem_max - alsa_mixer_elem_min) / (double) 255; break; } alsa_mixer_elem = snd_mixer_elem_next(alsa_mixer_elem); } } /* Set format variables. */ alsa_bits = (_sound_bits == 8) ? 8 : 16; alsa_stereo = (_sound_stereo) ? 1 : 0; alsa_rate = (_sound_freq > 0) ? _sound_freq : 44100; alsa_signed = 0; format = ((alsa_bits == 16) ? SND_PCM_FORMAT_U16_NE : SND_PCM_FORMAT_U8); switch (format) { case SND_PCM_FORMAT_U8: alsa_bits = 8; break; case SND_PCM_FORMAT_U16_NE: if (sizeof(short) != 2) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Unsupported sample format")); goto Error; } break; default: ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Unsupported sample format")); goto Error; } alsa_sample_size = (alsa_bits / 8) * (alsa_stereo ? 2 : 1); if (fragsize == 0) { unsigned int size = alsa_rate * ALSA_DEFAULT_BUFFER_MS / 1000 / numfrags; fragsize = 1; while (fragsize < size) fragsize <<= 1; } snd_pcm_hw_params_malloc(&hwparams); snd_pcm_sw_params_malloc(&swparams); ALSA9_CHECK(snd_pcm_hw_params_any(pcm_handle, hwparams)); ALSA9_CHECK(snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)); ALSA9_CHECK(snd_pcm_hw_params_set_format(pcm_handle, hwparams, format)); ALSA9_CHECK(snd_pcm_hw_params_set_channels(pcm_handle, hwparams, alsa_stereo + 1)); ALSA9_CHECK(snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &alsa_rate, NULL)); ALSA9_CHECK(snd_pcm_hw_params_set_period_size_near(pcm_handle, hwparams, &fragsize, NULL)); ALSA9_CHECK(snd_pcm_hw_params_set_periods_near(pcm_handle, hwparams, &numfrags, NULL)); ALSA9_CHECK(snd_pcm_hw_params(pcm_handle, hwparams)); ALSA9_CHECK(snd_pcm_hw_params_get_period_size(hwparams, &alsa_bufsize, NULL)); ALSA9_CHECK(snd_pcm_hw_params_get_periods(hwparams, &alsa_fragments, NULL)); TRACE (PREFIX_I "alsa_bufsize = %ld, alsa_fragments = %d\n", alsa_bufsize, alsa_fragments); ALSA9_CHECK(snd_pcm_sw_params_current(pcm_handle, swparams)); ALSA9_CHECK(snd_pcm_sw_params_set_start_threshold(pcm_handle, swparams, alsa_bufsize)); ALSA9_CHECK(snd_pcm_sw_params_set_avail_min(pcm_handle, swparams, fragsize)); ALSA9_CHECK(snd_pcm_sw_params_set_xfer_align(pcm_handle, swparams, 1)); ALSA9_CHECK(snd_pcm_sw_params(pcm_handle, swparams)); /* Allocate mixing buffer. */ alsa_bufdata = _AL_MALLOC_ATOMIC(alsa_bufsize * alsa_sample_size); if (!alsa_bufdata) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not allocate audio buffer")); goto Error; } /* Initialise mixer. */ digi_alsa.voices = voices; if (_mixer_init(alsa_bufsize * (alsa_stereo ? 2 : 1), alsa_rate, alsa_stereo, ((alsa_bits == 16) ? 1 : 0), &digi_alsa.voices) != 0) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not init software mixer")); goto Error; } snd_pcm_prepare(pcm_handle); pdc = snd_pcm_poll_descriptors_count (pcm_handle); if (pdc <= 0) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Invalid poll descriptors count")); goto Error; } ufds = _AL_MALLOC(sizeof(struct pollfd) * pdc); if (ufds == NULL) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Not enough memory for poll descriptors")); goto Error; } ALSA9_CHECK(snd_pcm_poll_descriptors(pcm_handle, ufds, pdc)); poll_next = 0; _mix_some_samples((uintptr_t) alsa_bufdata, 0, alsa_signed); /* Add audio interrupt. */ _unix_bg_man->register_func(alsa_update); uszprintf(alsa_desc, sizeof(alsa_desc), get_config_text ("Alsa 0.9, Device '%s': %d bits, %s, %d bps, %s"), alsa_device, alsa_bits, uconvert_ascii((alsa_signed ? "signed" : "unsigned"), tmp1), alsa_rate, uconvert_ascii((alsa_stereo ? "stereo" : "mono"), tmp2)); digi_driver->desc = alsa_desc; return 0; Error: if (pcm_handle) { snd_pcm_close(pcm_handle); pcm_handle = NULL; } return -1; }
int main() { const snd_pcm_channel_area_t *areas; int size; unsigned char *buffer; char *pcm_name; unsigned int rate = 44100; int chan; int rc; unsigned int val; char check; int pcmreturn; //Set PCM stream and handle snd_pcm_t *pcm_handle; snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK; //Set HARDWARE parameters snd_pcm_hw_params_t *hwparams; //pcm_name = (char *)malloc(10); pcm_name = "plughw:0,0"; //allocate memory for hardware if(snd_pcm_hw_params_malloc(&hwparams)<0) { fprintf(stderr,"No memory allocated for hardware"); return(-1); } if (snd_pcm_open(&pcm_handle, pcm_name, stream, 0) < 0) { fprintf(stderr, "Error opening PCM device %s\n", pcm_name); return(-1); } //INITIALIZE HARDWARE WITH CONFIGURATION OF THE SOUNDCARD if(snd_pcm_hw_params_any(pcm_handle,hwparams)<0) { fprintf(stderr,"The hardware device cannot be configured\n"); } //SET FORMAT TO 16 BIT LITTLE ENDIAN snd_pcm_hw_params_set_format(pcm_handle,hwparams,SND_PCM_FORMAT_S16_LE); /* Two channels (stereo) */ snd_pcm_hw_params_set_channels(pcm_handle,hwparams,2); /* 44100 bits/second sampling rate (CD quality) */ if (snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_MMAP_INTERLEAVED) < 0) { fprintf(stderr, "Error setting access.\n"); return(-1); } //SETTING RATE ie SAMPLING FREQUENCY snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &rate, 0); //SETTING HARDWARE PARAMETERS if(rc=(snd_pcm_hw_params(pcm_handle,hwparams))<0) { fprintf(stderr,"\nCannot set hardware parameters\n"); return -1; } //snd_pcm_uframes_t periodsize = 8192; snd_pcm_uframes_t frames,offset ;//OF TYPE UNSIGNED LONG snd_pcm_sframes_t commitres; frames =32; //SETTING SOME MORE PARAMETERS size = frames*4; //SETTING BUFFER SIZE /*if (snd_pcm_hw_params_set_buffer_size(pcm_handle, hwparams, (periodsize*2)>>2) < 0) { fprintf(stderr, "Error setting buffersize.\n"); return(-1); } */ int first=0;; int err; snd_pcm_sframes_t avail = snd_pcm_avail_update(pcm_handle); printf("\nNumber of frames available is : %d \n",(int)avail); //------------------------------------------------------------------------------------------------------- //<<<<<<<<<<<<<<<<<<<<<<DISPLAYING INFORMATION>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> //Buffer size snd_pcm_hw_params_get_buffer_size(hwparams, (snd_pcm_uframes_t*)&val); printf("\nThe buffer size is %d \n",val); //Buffer time snd_pcm_hw_params_get_buffer_time(hwparams, &val,0); printf("\nBuffer time is : %d \n",val); //Period size snd_pcm_hw_params_get_period_size(hwparams,&frames,0); printf("\nperiod size : %d \n",(int)frames); //Periods between buffers err=snd_pcm_mmap_begin(pcm_handle,&areas,&offset,&frames); //Periods between buffer snd_pcm_hw_params_get_periods(hwparams,&val,0); printf("\n Periods between buffer is : %d \n",val); //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>. if(err<0) { printf("\nMMAP error\n"); return -1; } else printf("\n%d\n",err); commitres = snd_pcm_mmap_commit(pcm_handle,offset,frames); if(commitres<0) { printf("\nFrames not committed to memory\n"); } int dest = open("sample3.wav",O_RDONLY); if(dest<0) { perror("\nFile could not be opened\n"); return -1; } //int *c = offset; buffer = (unsigned char *)malloc(1000); unsigned long buf = offset; if(read(dest,&offset,1)<0) { perror("\nNo destination for read\n"); return -1; } struct timeval tvbefore,tvafter; gettimeofday(&tvbefore,NULL); while(read(dest,buffer,100)!=0); gettimeofday(&tvafter,NULL); printf("\nTime taken by read() is %09ld \n",tvafter.tv_usec-tvbefore.tv_usec); /* while(1) { if(read(dest,&offset,80)!=0) { //fread(buffer,sizeof(buffer),160,f1); { if(pcmreturn = snd_pcm_mmap_writei(pcm_handle,&offset,80)<0) { snd_pcm_prepare(pcm_handle); printf("\n<<<<<<<Buffer Underrun>>>>>>>>\n"); break; } } } else break; } */ }
int main(int argc, char **argv) { long loops; int rc,j = 0; int size; snd_pcm_t *handle; snd_pcm_hw_params_t *params; unsigned int val,val2; int dir; snd_pcm_uframes_t frames; char *buffer; FILE *fp ; if((fp = fopen("audio.pcm", "r")) < 0) { printf("open sound.wav fial\n"); } /* Open PCM device for playback. */ rc = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 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 = 16; //设置的值没有反应 snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir); // printf("frames is %d\n",(int)frames); /* 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); /* 5 seconds in microseconds divided by * period time */ loops = 10000000 / val; while (loops > 0) { loops--; //rc = fread(buffer,1, size,fp); rc = read(0, buffer, size); //printf("%d\n",j++); if (rc == 0) { fprintf(stderr, "end of file on input\n"); break; } else if (rc != size) { fprintf(stderr, "short read: read %d bytes\n", rc); } //else printf("fread to buffer success\n"); rc = snd_pcm_writei(handle, buffer, frames); if (rc == -EPIPE) { /* EPIPE means underrun */ fprintf(stderr, "underrun occurred\n"); snd_pcm_prepare(handle); } else if (rc < 0) { fprintf(stderr, "error from writei: %s\n", snd_strerror(rc)); } else if (rc != (int)frames) { fprintf(stderr, "short write, write %d frames\n", rc); } } /******************打印参数*********************/ 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); free(buffer); fclose(fp); return 0; }
static ALCboolean alsa_reset_playback(ALCdevice *device) { alsa_data *data = (alsa_data*)device->ExtraData; snd_pcm_uframes_t periodSizeInFrames; unsigned int periodLen, bufferLen; snd_pcm_sw_params_t *sp = NULL; snd_pcm_hw_params_t *p = NULL; snd_pcm_access_t access; snd_pcm_format_t format; unsigned int periods; unsigned int rate; int allowmmap; char *err; int i; format = -1; switch(device->FmtType) { case DevFmtByte: format = SND_PCM_FORMAT_S8; break; case DevFmtUByte: format = SND_PCM_FORMAT_U8; break; case DevFmtShort: format = SND_PCM_FORMAT_S16; break; case DevFmtUShort: format = SND_PCM_FORMAT_U16; break; case DevFmtFloat: format = SND_PCM_FORMAT_FLOAT; break; } allowmmap = GetConfigValueBool("alsa", "mmap", 1); periods = device->NumUpdates; periodLen = (ALuint64)device->UpdateSize * 1000000 / device->Frequency; bufferLen = periodLen * periods; rate = device->Frequency; err = NULL; snd_pcm_hw_params_malloc(&p); if((i=snd_pcm_hw_params_any(data->pcmHandle, p)) < 0) err = "any"; /* set interleaved access */ if(i >= 0 && (!allowmmap || (i=snd_pcm_hw_params_set_access(data->pcmHandle, p, SND_PCM_ACCESS_MMAP_INTERLEAVED)) < 0)) { if(periods > 2) { periods--; bufferLen = periodLen * periods; } if((i=snd_pcm_hw_params_set_access(data->pcmHandle, p, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) err = "set access"; } /* set format (implicitly sets sample bits) */ if(i >= 0 && (i=snd_pcm_hw_params_set_format(data->pcmHandle, p, format)) < 0) { device->FmtType = DevFmtFloat; if(format == SND_PCM_FORMAT_FLOAT || (i=snd_pcm_hw_params_set_format(data->pcmHandle, p, SND_PCM_FORMAT_FLOAT)) < 0) { device->FmtType = DevFmtShort; if(format == SND_PCM_FORMAT_S16 || (i=snd_pcm_hw_params_set_format(data->pcmHandle, p, SND_PCM_FORMAT_S16)) < 0) { device->FmtType = DevFmtUByte; if(format == SND_PCM_FORMAT_U8 || (i=snd_pcm_hw_params_set_format(data->pcmHandle, p, SND_PCM_FORMAT_U8)) < 0) err = "set format"; } } } /* set channels (implicitly sets frame bits) */ if(i >= 0 && (i=snd_pcm_hw_params_set_channels(data->pcmHandle, p, ChannelsFromDevFmt(device->FmtChans))) < 0) { if((i=snd_pcm_hw_params_set_channels(data->pcmHandle, p, 2)) < 0) { if((i=snd_pcm_hw_params_set_channels(data->pcmHandle, p, 1)) < 0) err = "set channels"; else device->FmtChans = DevFmtMono; } else device->FmtChans = DevFmtStereo; } if(i >= 0 && (i=snd_pcm_hw_params_set_rate_resample(data->pcmHandle, p, 0)) < 0) { ERR("Failed to disable ALSA resampler\n"); i = 0; } /* set rate (implicitly constrains period/buffer parameters) */ if(i >= 0 && (i=snd_pcm_hw_params_set_rate_near(data->pcmHandle, p, &rate, NULL)) < 0) err = "set rate near"; /* set buffer time (implicitly constrains period/buffer parameters) */ if(i >= 0 && (i=snd_pcm_hw_params_set_buffer_time_near(data->pcmHandle, p, &bufferLen, NULL)) < 0) err = "set buffer time near"; /* set period time in frame units (implicitly sets buffer size/bytes/time and period size/bytes) */ if(i >= 0 && (i=snd_pcm_hw_params_set_period_time_near(data->pcmHandle, p, &periodLen, NULL)) < 0) err = "set period time near"; /* install and prepare hardware configuration */ if(i >= 0 && (i=snd_pcm_hw_params(data->pcmHandle, p)) < 0) err = "set params"; if(i >= 0 && (i=snd_pcm_hw_params_get_access(p, &access)) < 0) err = "get access"; if(i >= 0 && (i=snd_pcm_hw_params_get_period_size(p, &periodSizeInFrames, NULL)) < 0) err = "get period size"; if(i >= 0 && (i=snd_pcm_hw_params_get_periods(p, &periods, NULL)) < 0) err = "get periods"; if(i < 0) { ERR("%s failed: %s\n", err, snd_strerror(i)); snd_pcm_hw_params_free(p); return ALC_FALSE; } snd_pcm_hw_params_free(p); err = NULL; snd_pcm_sw_params_malloc(&sp); if((i=snd_pcm_sw_params_current(data->pcmHandle, sp)) != 0) err = "sw current"; if(i == 0 && (i=snd_pcm_sw_params_set_avail_min(data->pcmHandle, sp, periodSizeInFrames)) != 0) err = "sw set avail min"; if(i == 0 && (i=snd_pcm_sw_params_set_stop_threshold(data->pcmHandle, sp, periodSizeInFrames*periods)) != 0) err = "sw set stop threshold"; if(i == 0 && (i=snd_pcm_sw_params(data->pcmHandle, sp)) != 0) err = "sw set params"; if(i != 0) { ERR("%s failed: %s\n", err, snd_strerror(i)); snd_pcm_sw_params_free(sp); return ALC_FALSE; } snd_pcm_sw_params_free(sp); device->Frequency = rate; SetDefaultChannelOrder(device); data->size = snd_pcm_frames_to_bytes(data->pcmHandle, periodSizeInFrames); if(access == SND_PCM_ACCESS_RW_INTERLEAVED) { /* Increase periods by one, since the temp buffer counts as an extra * period */ periods++; data->buffer = malloc(data->size); if(!data->buffer) { ERR("buffer malloc failed\n"); return ALC_FALSE; } device->UpdateSize = periodSizeInFrames; device->NumUpdates = periods; data->thread = StartThread(ALSANoMMapProc, device); } else { i = snd_pcm_prepare(data->pcmHandle); if(i < 0) { ERR("prepare error: %s\n", snd_strerror(i)); return ALC_FALSE; } device->UpdateSize = periodSizeInFrames; device->NumUpdates = periods; data->thread = StartThread(ALSAProc, device); } if(data->thread == NULL) { ERR("Could not create playback thread\n"); free(data->buffer); data->buffer = NULL; return ALC_FALSE; } return ALC_TRUE; }