//_______________________________________________ // // //_______________________________________________ uint8_t coreAudioDevice::play(uint32_t len, float *data) { // First put stuff into the buffer uint8_t *src; uint32_t left; dither16(data, len, _channels); pthread_mutex_lock(&lock); // Check we have room left if(wr_ptr>=rd_ptr) { left=BUFFER_SIZE-(wr_ptr-rd_ptr); } else { left=rd_ptr-wr_ptr; } if(len+1>left) { printf("AudioCore:Buffer full!\n"); pthread_mutex_unlock(&lock); return 0; } // We have room left, copy it src=(uint8_t *)&audioBuffer[wr_ptr]; if(wr_ptr+len<BUFFER_SIZE) { memcpy(src,data,len*2); wr_ptr+=len; } else { left=BUFFER_SIZE-wr_ptr-1; memcpy(src,data,left*2); memcpy(audioBuffer,data+left*2,(len-left)*2); wr_ptr=len-left; } //aprintf("AudioCore: Putting %lu bytes rd:%lu wr:%lu \n",len*2,rd_ptr,wr_ptr); pthread_mutex_unlock(&lock); if(!frameCount) { _inUse=1; verify_noerr(AudioOutputUnitStart(theOutputUnit)); } return 1; }
//_______________________________________________ // // //_______________________________________________ uint8_t ossAudioDevice::play(uint32_t len, float *data) { uint32_t w; if (!oss_fd) return 0; dither16(data, len, _channels); w = write(oss_fd, data, len*2); if(w!=len*2) { printf("[OSS] Warning : %u / %u\n",w,len*2); } return 1; }
/** \fn play */ uint8_t audioDeviceThreaded::play(uint32_t len, float *data) { // Reorder channels if needed... uint32_t samples=len; samples/=_channels; ADM_audioReorderChannels(_channels, (float *)(data), samples, incomingMapping, (CHANNEL_TYPE*)getWantedChannelMapping(_channels)); // dither to int16_t dither16(data, len, _channels); len*=2; // Store in buffer return writeData((uint8_t *)data,len); }
uint8_t win32AudioDevice::play(uint32_t len, float *data) { if (len == 0) return 1; dither16(data, len, _channels); len *= 2; uint8_t success = 0; for (uint32_t i = 0; i < NB_BUCKET; i++) { if (waveHdr[i].dwFlags & WHDR_DONE) { waveHdr[i].dwFlags &= ~WHDR_DONE; if (len > bucketSize) waveHdr[i].dwBufferLength = bucketSize; else waveHdr[i].dwBufferLength = len; memcpy(waveHdr[i].lpData, data, waveHdr[i].dwBufferLength); data += waveHdr[i].dwBufferLength; len -= waveHdr[i].dwBufferLength; if (waveOutWrite(myDevice, &waveHdr[i], sizeof(WAVEHDR)) == MMSYSERR_NOERROR) success = 1; else break; } if (len == 0) break; } if (len != 0) { printf("[Win32] No audio buffer available, %u bytes discarded\n", len); return 0; } return success; }
/** \fn send \brief Encode a block */ int AUDMEncoder_Lame::send(uint32_t nbSample, uint8_t *dest) { int nbout; dither16 (&(tmpbuffer[tmphead]), nbSample, wavheader.channels); ADM_assert (tmptail >= tmphead); int16_t *sample16=(int16_t *)& (tmpbuffer[tmphead]); if (wavheader.channels == 1) { nbout = lame_encode_buffer (MYFLAGS, sample16, sample16, nbSample, dest, 16 * 1024); } else { nbout = lame_encode_buffer_interleaved (MYFLAGS, sample16, nbSample / 2, dest, 16 * 1024); } return nbout; }
uint8_t AUDMEncoder_PCM::getPacket(uint8_t *dest, uint32_t *len, uint32_t *samples) { uint32_t nbout; *samples = _chunk; //FIXME *len = 0; if(!refillBuffer(_chunk )) { return 0; } if(tmptail-tmphead<_chunk) { return 0; } // Do in place replace dither16(&(tmpbuffer[tmphead]),_chunk,_wavheader->channels); if(!revert) memcpy(dest,&(tmpbuffer[tmphead]),_chunk*2); else { uint16_t *in,*out,tmp; in=(uint16_t*)&(tmpbuffer[tmphead]); out=(uint16_t *)dest; for(int i=0;i<_chunk;i++) { tmp=*in++; tmp=((tmp&0xff)<<8)+(tmp>>8); *out++=tmp; } } tmphead+=_chunk; *len=_chunk*2; *samples=_chunk/_wavheader->channels; return 1; }
/** \fn getPacket */ bool AUDMEncoder_Twolame::encode(uint8_t *dest, uint32_t *len, uint32_t *samples) { int nbout; int channels=wavheader.channels; *samples = 1152; //FIXME *len = 0; ADM_assert(tmptail>=tmphead); if(!refillBuffer(_chunk )) { return false; } if(tmptail-tmphead<_chunk) { return false; } dither16(&(tmpbuffer[tmphead]),_chunk,channels); ADM_assert(tmptail>=tmphead); if (channels == 1) { nbout =twolame_encode_buffer(OPTIONS, (int16_t *)&(tmpbuffer[tmphead]),(int16_t *)&(tmpbuffer[tmphead]), _chunk, dest, 16 * 1024); } else { nbout = twolame_encode_buffer_interleaved(OPTIONS, (int16_t *)&(tmpbuffer[tmphead]), _chunk/2, dest, 16 * 1024); } tmphead+=_chunk; ADM_assert(tmptail>=tmphead); if (nbout < 0) { printf("[TwoLame] Error !!! : %d\n", nbout); return false; } *len=nbout; return true; }
uint8_t AUDMEncoder_Twolame::getPacket(uint8_t *dest, uint32_t *len, uint32_t *samples) { int nbout; *samples = 1152; //FIXME *len = 0; ADM_assert(tmptail>=tmphead); if(!refillBuffer(_chunk )) { return 0; } if(tmptail-tmphead<_chunk) { return 0; } dither16(&(tmpbuffer[tmphead]),_chunk,_wavheader->channels); ADM_assert(tmptail>=tmphead); if (_wavheader->channels == 1) { nbout =twolame_encode_buffer(OPTIONS, (int16_t *)&(tmpbuffer[tmphead]),(int16_t *)&(tmpbuffer[tmphead]), _chunk, dest, 16 * 1024); } else { nbout = twolame_encode_buffer_interleaved(OPTIONS, (int16_t *)&(tmpbuffer[tmphead]), _chunk/2, dest, 16 * 1024); } tmphead+=_chunk; ADM_assert(tmptail>=tmphead); if (nbout < 0) { printf("\n Error !!! : %ld\n", nbout); return 0; } *len=nbout; return 1; }
uint8_t AUDMEncoder_Lame::getPacket(uint8_t *dest, uint32_t *len, uint32_t *samples) { int32_t nbout; *samples = BLOCK_SIZE; //FIXME *len = 0; if(!refillBuffer(_chunk )) { return 0; } if(tmptail-tmphead<_chunk) { return 0; } dither16(&(tmpbuffer[tmphead]),_chunk,_wavheader->channels); ADM_assert(tmptail>=tmphead); if (_wavheader->channels == 1) { nbout = lame_encode_buffer(MYFLAGS, (int16_t *)&(tmpbuffer[tmphead]),(int16_t *)&(tmpbuffer[tmphead]), _chunk, dest, 16 * 1024); } else { nbout = lame_encode_buffer_interleaved(MYFLAGS, (int16_t *)&(tmpbuffer[tmphead]), _chunk/2, dest, 16 * 1024); } tmphead+=_chunk; if (nbout < 0) { printf("\n Error !!! : %ld\n", nbout); return 0; } *len=nbout; if(!*len) *samples=0; //printf("Audio packet : size %u, sample %u\n",*len,*samples); return 1; }
/** \fn encode */ bool AUDMEncoder_Lavcodec::encode(uint8_t *dest, uint32_t *len, uint32_t *samples) { uint32_t nbout; int retries=16; again: int channels=wavheader.channels; *samples = _chunk/channels; //FIXME *len = 0; if(AudioEncoderStopped==_state) return false; refillBuffer (_chunk); if(AudioEncoderNoInput==_state) { int left=tmptail-tmphead; if (left < _chunk) { if(left) // Last block { if(_useFloat==false) dither16(&(tmpbuffer[tmphead]),left,channels); ADM_assert(tmptail>=tmphead); //#warning buffer overread nbout = avcodec_encode_audio(CONTEXT, dest, 5000, (short *) &(tmpbuffer[tmphead])); tmphead=tmptail; *samples = left/channels; *len=nbout; ADM_info("[Lav] Last audio block\n"); goto cnt; } // Flush ADM_info("[Lav] Flush\n"); _state=AudioEncoderStopped; if(CONTEXT->codec->capabilities & CODEC_CAP_DELAY) { nbout=avcodec_encode_audio(CONTEXT, dest, 5000,NULL); if(nbout<0) { ADM_warning("Error while flushing lame\n"); return false; } *len=nbout; *samples=_chunk/channels; ADM_info("[Lav] Flushing, last block is %d bytes\n",nbout); return true; }else { } ADM_info("[Lav] No data to flush\n",nbout); return true; } } if(_useFloat==false) dither16(&(tmpbuffer[tmphead]),_chunk,channels); ADM_assert(tmptail>=tmphead); nbout = avcodec_encode_audio(CONTEXT, dest, 5000, (short *) &(tmpbuffer[tmphead])); tmphead+=_chunk; cnt: if(!nbout && retries) { retries--; ADM_info("Audio encoder (lav): no packet, retrying\n"); goto again; } if (nbout < 0) { ADM_error("[Lavcodec] Error !!! : %"PRIi32"\n", nbout); return 0; } *len=nbout; *samples=_chunk/channels; return true; }
//_______________________________________________ // // //_______________________________________________ uint8_t esdAudioDevice::play(uint32_t len, float *data) { dither16(data, len, _channels); write(esdDevice, data, len*2); return 1; }