static snd_pcm_sframes_t snd_pcm_ioplug_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size) { if (pcm->mmap_rw) return snd_pcm_mmap_writei(pcm, buffer, size); else { snd_pcm_channel_area_t areas[pcm->channels]; snd_pcm_areas_from_buf(pcm, areas, (void*)buffer); return snd_pcm_write_areas(pcm, areas, 0, size, ioplug_priv_transfer_areas); } }
static int play(struct audio_play *play) { int err, len; char *ptr; ptr = buf; len = play->nsamples; audio_pcm(ptr, len, play->samples[0], play->samples[1], play->mode, play->stats); while (len > 0) { err = snd_pcm_mmap_writei(alsa_handle, ptr, len); if (err == -EAGAIN) continue; if (err < 0) { if (xrun_recovery(alsa_handle, err) < 0) { audio_error = snd_strerror(err); return -1; } break; } len -= err; ptr += err * sample_size; } return 0; }
long OutputALSA::alsa_write(unsigned char *data, long size) { long m = snd_pcm_avail_update(pcm_handle); if(m >= 0 && m < size) { snd_pcm_wait(pcm_handle, 500); return 0; } if (m_use_mmap) m = snd_pcm_mmap_writei (pcm_handle, data, size); else m = snd_pcm_writei (pcm_handle, data, size); if (m == -EAGAIN) { snd_pcm_wait(pcm_handle, 500); return 0; } else if (m >= 0) { if (m < size) { snd_pcm_wait(pcm_handle, 500); } return m; } else if (m == -EPIPE) { qDebug ("OutputALSA: buffer underrun!"); if ((m = snd_pcm_prepare(pcm_handle)) < 0) { qDebug ("OutputALSA: Can't recover after underrun: %s", snd_strerror(m)); /* TODO: reopen the device */ return -1; } return 0; } #ifdef ESTRPIPE else if (m == -ESTRPIPE) { qDebug ("OutputALSA: Suspend, trying to resume"); while ((m = snd_pcm_resume(pcm_handle)) == -EAGAIN) sleep (1); if (m < 0) { qDebug ("OutputALSA: Failed, restarting"); if ((m = snd_pcm_prepare(pcm_handle)) < 0) { qDebug ("OutputALSA: Failed to restart device: %s.", snd_strerror(m)); return -1; } } return 0; } #endif qDebug ("OutputALSA: error: %s", snd_strerror(m)); return snd_pcm_prepare (pcm_handle); }
int main() { const snd_pcm_channel_area_t *areas; int size; unsigned char *buffer; char *pcm_name; unsigned int rate = 8000; 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); //////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////// //<<<<<<<<<<<<<mmap_begin>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 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"); } */ //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<,OPENING FILE>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>.... int dest = open("sample3.wav",O_RDONLY); if(dest<0) { perror("\nFile could not be opened\n"); return -1; } //buffer = (unsigned char *)malloc(1000); /* unsigned long buf = offset; if(read(dest,&offset,1)<0) { perror("\nNo destination for read\n"); return -1; } */ /* avail=snd_pcm_avail_update(pcm_handle); printf("\nAvailable frames = %d \n\n",(int)avail); struct timeval tvbefore,tvafter; gettimeofday(&tvbefore,NULL); */ unsigned char *ptr[2]; int i; //unsigned int steps=0; for(i=0;i<2;i++) ptr[i] = (unsigned char*)areas[i].addr + (areas[i].first/8) + offset*(areas[i].step/8); printf("\nOffset of the first sample : %u \n",areas[0].first); printf("\n\nOffset of the memory map is : %u \n",areas[0].step/8); printf("\nAreas start address is : %u \n",areas[0].addr); printf("\nNumber of frames ; %u \n",frames); printf("\n\nPointer before ; %u \n",ptr[0]); long pl; for(pl=0;pl<100000;pl++); if(ptr[1]==NULL) printf("\nNull pointer 1 allocated\n"); if(ptr[0]==NULL) printf("\nNull pointer 0 allocated \n"); int check2=1; snd_pcm_sframes_t size2 =30; while(1) { for(i=0;i<2;i++) { //ptr[i] = (unsigned char*)areas[i].addr + (areas[i].first/8) + offset*(areas[i].step/8); if(read(dest,ptr[i],120)!=0) { if(ptr[i]!=NULL) { if(pcmreturn = snd_pcm_mmap_writei(pcm_handle,ptr[i],size2)<0) { snd_pcm_prepare(pcm_handle); printf("\n<<<<<<<Buffer Underrun>>>>>>>>\n"); break; } // printf("\n%d\n",pcmreturn); ptr[i]+=0; printf("\n%lu\n",ptr[i]); } } else { check2=0; break; } } if(check2==0) break; // l:break; } commitres = snd_pcm_mmap_commit(pcm_handle,offset,frames); if(commitres<0) { printf("\nFrames not committed to memory\n"); } }
ssize_t AudioStreamOutALSA::write(const void *buffer, size_t bytes) { android::AutoMutex lock(mLock); if (!mPowerLock) { acquire_wake_lock (PARTIAL_WAKE_LOCK, "AudioOutLock"); mPowerLock = true; } acoustic_device_t *aDev = acoustics(); // For output, we will pass the data on to the acoustics module, but the actual // data is expected to be sent to the audio device directly as well. if (aDev && aDev->write) aDev->write(aDev, buffer, bytes); snd_pcm_sframes_t n; size_t sent = 0; status_t err = 0; do { if (mHandle->mmap) n = snd_pcm_mmap_writei(mHandle->handle, (char *)buffer + sent, snd_pcm_bytes_to_frames(mHandle->handle, bytes - sent)); else n = snd_pcm_writei(mHandle->handle, (char *)buffer + sent, snd_pcm_bytes_to_frames(mHandle->handle, bytes - sent)); if (n == -EBADFD) { LOGW("badstate and do recovery....."); switch(snd_pcm_state(mHandle->handle)){ case SND_PCM_STATE_SETUP: err = snd_pcm_prepare(mHandle->handle); if(err < 0) LOGW("snd_pcm_prepare failed"); break; case SND_PCM_STATE_SUSPENDED: snd_pcm_resume(mHandle->handle); if(err < 0) LOGW("snd_pcm_resume failed"); snd_pcm_prepare(mHandle->handle); if(err < 0) LOGW("snd_pcm_prepare failed"); break; default: // Somehow the stream is in a bad state. The driver probably // has a bug and snd_pcm_recover() doesn't seem to handle this. mHandle->module->open(mHandle, mHandle->curDev, mHandle->curMode); break; } if(err < 0 ) mHandle->module->open(mHandle, mHandle->curDev, mHandle->curMode); if (aDev && aDev->recover) aDev->recover(aDev, n); } else if (n < 0) { if (mHandle->handle) { LOGW("underrun and do recovery....."); // snd_pcm_recover() will return 0 if successful in recovering from // an error, or -errno if the error was unrecoverable. n = snd_pcm_recover(mHandle->handle, n, 1); if (aDev && aDev->recover) aDev->recover(aDev, n); if (n) return static_cast<ssize_t>(n); } } else { mFrameCount += n; sent += static_cast<ssize_t>(snd_pcm_frames_to_bytes(mHandle->handle, n)); } } while (mHandle->handle && sent < bytes); return sent; }