void CPSampleManager::copy_to(CPSample_ID p_from,CPSample_ID &p_to) { ERR_FAIL_COND(!check( p_from )); if (p_to.is_null()) { p_to=create( is_16bits( p_from), is_stereo( p_from), get_size(p_from)); } else { recreate( p_to, is_16bits( p_from), is_stereo( p_from), get_size(p_from)); } int len=get_size( p_from ); int ch=is_stereo( p_from ) ? 2 : 1; for (int c=0;c<ch;c++) { for (int i=0;i<len;i++) { int16_t s=get_data( p_from, i, c ); set_data( p_to, i, s, c ); } } set_loop_type( p_to, get_loop_type( p_from ) ); set_loop_begin( p_to, get_loop_begin( p_from ) ); set_loop_end( p_to, get_loop_end( p_from ) ); set_c5_freq( p_to, get_c5_freq( p_from ) ); }
unsigned AudioDevice::bufStereo(Linear samples, unsigned count) { unsigned fill, index; Sample mbuf[80]; unsigned total = 0; if(is_stereo(info.encoding)) return putSamples(samples, count); while(count) { if(count < 80) fill = count; else fill = 80; for(index = 0; index < fill; ++ index) mbuf[index] = samples[index * 2] / 2 + samples[index * 2 + 1] / 2; total += putSamples(mbuf, fill); count -= fill; samples += (fill * 2); } return total; }
unsigned AudioStream::getMono(Linear buffer, unsigned frames) { unsigned char *iobuf = (unsigned char *)buffer; unsigned count, offset, copied = 0; ssize_t len; Linear dbuf = NULL; if(!is_streamable()) return 0; if(!frames) ++frames; count = frames * getCount(); if(is_stereo(info.encoding)) dbuf = new Sample[count * 2]; if(codec) iobuf = framebuf; else if(dbuf) iobuf = (unsigned char *)dbuf; while(frames--) { len = AudioFile::getBuffer(iobuf); // packet read if(len < (ssize_t)info.framesize) break; ++copied; if(codec) { codec->decode(buffer, iobuf, info.framecount); goto stereo; } if(dbuf) swapEndian(info, dbuf, info.framecount); else swapEndian(info, buffer, info.framecount); stereo: if(!dbuf) { buffer += info.framecount; continue; } for(offset = 0; offset < info.framecount; ++offset) buffer[offset] = dbuf[offset * 2] / 2 + dbuf[offset * 2 + 1] / 2; buffer += info.framecount; } if(dbuf) delete[] dbuf; return copied; }
bool Audio::swapEndian(Info &info, void *buffer, unsigned samples) { unsigned char buf; unsigned char *s1, *s2, *s3, *s4; if(is_stereo(info.encoding)) samples *= 2; switch(info.encoding) { case pcm16Mono: case pcm16Stereo: case cdaMono: case cdaStereo: if(__BYTE_ORDER == info.order || !info.order) return true; s1 = (unsigned char *)buffer; s2 = s1 + 1; while(samples--) { buf = *s1; *s1 = *s2; *s2 = buf; s1 += 2; s2 += 2; } return false; case pcm32Mono: case pcm32Stereo: if(__BYTE_ORDER == info.order || !info.order) return true; s1 = (unsigned char *)buffer; s2 = s1 + 1; s3 = s2 + 1; s4 = s3 + 1; while(samples--) { buf = *s1; *s1 = *s4; *s4 = buf; buf = *s2; *s2 = *s3; *s3 = buf; s1 += 4; s2 += 4; s3 += 4; s4 += 4; } return false; default: return true; } }
Dictionary Sample::_get_data() const { Dictionary d; switch(get_format()) { case FORMAT_PCM8: d["format"]="pcm8"; break; case FORMAT_PCM16: d["format"]="pcm16"; break; case FORMAT_IMA_ADPCM: d["format"]="ima_adpcm"; break; } d["stereo"]=is_stereo(); d["length"]=get_length(); d["packing"]="raw"; d["data"]=get_data(); return d; }
unsigned AudioStream::putMono(Linear buffer, unsigned frames) { Linear iobuf = buffer, dbuf = NULL; unsigned offset, copied = 0; ssize_t len; if(!is_streamable()) return 0; if(!frames) ++frames; if(is_stereo(info.encoding)) { dbuf = new Sample[info.framecount * 2]; iobuf = dbuf; } while(frames--) { if(dbuf) { for(offset = 0; offset < info.framecount; ++offset) dbuf[offset * 2] = dbuf[offset * 2 + 1] = buffer[offset]; } if(codec) { codec->encode(iobuf, framebuf, info.framecount); len = putBuffer(framebuf); if(len < (ssize_t)info.framesize) break; ++copied; buffer += info.framecount; continue; } swapEndian(info, iobuf, info.framecount); len = putBuffer((Encoded)iobuf); if(len < (ssize_t)info.framesize) break; ++copied; buffer += info.framecount; } if(dbuf) delete[] dbuf; return copied; }
unsigned AudioStream::getStereo(Linear buffer, unsigned frames) { unsigned char *iobuf = (unsigned char *)buffer; unsigned offset, copied = 0; ssize_t len; if(!is_streamable()) return 0; if(!frames) ++frames; if(codec) iobuf = framebuf; while(frames--) { len = AudioFile::getBuffer(iobuf); // packet read if(len < (ssize_t)info.framesize) break; ++copied; if(codec) { codec->decode(buffer, iobuf, info.framecount); goto stereo; } swapEndian(info, buffer, info.framecount); stereo: if(is_stereo(info.encoding)) { buffer += (info.framecount * 2); continue; } offset = info.framecount; while(offset--) { buffer[offset * 2] = buffer[offset]; buffer[offset * 2 + 1] = buffer[offset]; } buffer += (info.framecount * 2); } return copied; }
void SampleManager_MemPool::fix_loop_end(Sample_ID p_id) { /* Set the last frame to the begining of the loop, so interpolation works well */ int ch=is_stereo( p_id) ?2:1; for (int i=0;i<ch;i++) { set_data( p_id, -1, 0 , i ); } if (get_loop_type( p_id)!=LOOP_NONE && get_loop_end( p_id)==get_size( p_id) ) { if (get_loop_type( p_id)==LOOP_FORWARD) { for (int i=0;i<ch;i++) { set_data( p_id, get_size( p_id), get_data( p_id, get_loop_begin( p_id) + 1, i ), i ); set_data( p_id, get_size( p_id)+1, get_data( p_id, get_loop_begin( p_id) + 1, i ), i ); } } else { for (int i=0;i<ch;i++) { set_data( p_id, get_size( p_id), get_data( p_id, get_loop_end( p_id) -1 , i ), i ); set_data( p_id, get_size( p_id)+1, get_data( p_id, get_loop_end( p_id) -1 , i ), i ); } } } else { for (int i=0;i<ch;i++) { set_data( p_id, get_size( p_id), 0 , i ); set_data( p_id, get_size( p_id)+1, 0 , i ); } } }
unsigned AudioDevice::bufMono(Linear samples, unsigned count) { unsigned fill, index; Sample sbuf[160]; unsigned total = 0; if(!is_stereo(info.encoding)) return putSamples(samples, count); while(count) { if(count < 80) fill = count; else fill = 80; for(index = 0; index < fill; ++ index) sbuf[index * 2] = sbuf[index * 2 + 1] = samples[index]; total += putSamples(sbuf, fill * 2); count -= fill; samples += fill; } return total; }