void AUD_FileWriter::writeReader(AUD_Reference<AUD_IReader> reader, AUD_Reference<AUD_IWriter> writer, unsigned int length, unsigned int buffersize) { AUD_Buffer buffer(buffersize * AUD_SAMPLE_SIZE(writer->getSpecs())); sample_t* buf = buffer.getBuffer(); int len; bool eos = false; int channels = writer->getSpecs().channels; for(unsigned int pos = 0; ((pos < length) || (length <= 0)) && !eos; pos += len) { len = buffersize; if((len > length - pos) && (length > 0)) len = length - pos; reader->read(len, eos, buf); for(int i = 0; i < len * channels; i++) { // clamping! if(buf[i] > 1) buf[i] = 1; else if(buf[i] < -1) buf[i] = -1; } writer->write(len, buf); } }
void AUD_FileWriter::writeReader(AUD_Reference<AUD_IReader> reader, std::vector<AUD_Reference<AUD_IWriter> >& writers, unsigned int length, unsigned int buffersize) { AUD_Buffer buffer(buffersize * AUD_SAMPLE_SIZE(reader->getSpecs())); AUD_Buffer buffer2(buffersize * sizeof(sample_t)); sample_t* buf = buffer.getBuffer(); sample_t* buf2 = buffer2.getBuffer(); int len; bool eos = false; int channels = reader->getSpecs().channels; for(unsigned int pos = 0; ((pos < length) || (length <= 0)) && !eos; pos += len) { len = buffersize; if((len > length - pos) && (length > 0)) len = length - pos; reader->read(len, eos, buf); for(int channel = 0; channel < channels; channel++) { for(int i = 0; i < len; i++) { // clamping! if(buf[i * channels + channel] > 1) buf2[i] = 1; else if(buf[i * channels + channel] < -1) buf2[i] = -1; else buf2[i] = buf[i * channels + channel]; } writers[channel]->write(len, buf2); } } }
AUD_DoubleReader::AUD_DoubleReader(AUD_Reference<AUD_IReader> reader1, AUD_Reference<AUD_IReader> reader2) : m_reader1(reader1), m_reader2(reader2), m_finished1(false) { AUD_Specs s1, s2; s1 = reader1->getSpecs(); s2 = reader2->getSpecs(); }
AUD_Reference<AUD_IReader> AUD_EnvelopeFactory::createReader() { AUD_Reference<AUD_IReader> reader = getReader(); EnvelopeParameters* param = new EnvelopeParameters(); param->arthreshold = m_arthreshold; param->attack = pow(m_arthreshold, 1.0f/(static_cast<float>(reader->getSpecs().rate) * m_attack)); param->release = pow(m_arthreshold, 1.0f/(static_cast<float>(reader->getSpecs().rate) * m_release)); param->threshold = m_threshold; return new AUD_CallbackIIRFilterReader(reader, 1, 2, (doFilterIIR) envelopeFilter, (endFilterIIR) endEnvelopeFilter, param); }
AUD_SoundInfo AUD_getInfo(AUD_Sound* sound) { assert(sound); AUD_SoundInfo info; info.specs.channels = AUD_CHANNELS_INVALID; info.specs.rate = AUD_RATE_INVALID; info.length = 0.0f; try { AUD_Reference<AUD_IReader> reader = (*sound)->createReader(); if(!reader.isNull()) { info.specs = reader->getSpecs(); info.length = reader->getLength() / (float) info.specs.rate; } } catch(AUD_Exception&) { } return info; }
float* AUD_readSoundBuffer(const char* filename, float low, float high, float attack, float release, float threshold, int accumulate, int additive, int square, float sthreshold, double samplerate, int* length) { AUD_Buffer buffer; AUD_DeviceSpecs specs; specs.channels = AUD_CHANNELS_MONO; specs.rate = (AUD_SampleRate)samplerate; AUD_Reference<AUD_IFactory> sound; AUD_Reference<AUD_IFactory> file = new AUD_FileFactory(filename); AUD_Reference<AUD_IReader> reader = file->createReader(); AUD_SampleRate rate = reader->getSpecs().rate; sound = new AUD_ChannelMapperFactory(file, specs); if(high < rate) sound = new AUD_LowpassFactory(sound, high); if(low > 0) sound = new AUD_HighpassFactory(sound, low); sound = new AUD_EnvelopeFactory(sound, attack, release, threshold, 0.1f); sound = new AUD_LinearResampleFactory(sound, specs); if(square) sound = new AUD_SquareFactory(sound, sthreshold); if(accumulate) sound = new AUD_AccumulatorFactory(sound, additive); else if(additive) sound = new AUD_SumFactory(sound); reader = sound->createReader(); if(reader.isNull()) return NULL; int len; int position = 0; bool eos; do { len = samplerate; buffer.resize((position + len) * sizeof(float), true); reader->read(len, eos, buffer.getBuffer() + position); position += len; } while(!eos); float* result = (float*)malloc(position * sizeof(float)); memcpy(result, buffer.getBuffer(), position * sizeof(float)); *length = position; return result; }
AUD_BaseIIRFilterReader::AUD_BaseIIRFilterReader(AUD_Reference<AUD_IReader> reader, int in, int out) : AUD_EffectReader(reader), m_specs(reader->getSpecs()), m_xlen(in), m_ylen(out), m_xpos(0), m_ypos(0), m_channel(0) { m_x = new sample_t[m_xlen * m_specs.channels]; m_y = new sample_t[m_ylen * m_specs.channels]; memset(m_x, 0, sizeof(sample_t) * m_xlen * m_specs.channels); memset(m_y, 0, sizeof(sample_t) * m_ylen * m_specs.channels); }
int AUD_readSound(AUD_Sound* sound, sample_t* buffer, int length, int samples_per_second) { AUD_DeviceSpecs specs; sample_t* buf; AUD_Buffer aBuffer; specs.rate = AUD_RATE_INVALID; specs.channels = AUD_CHANNELS_MONO; specs.format = AUD_FORMAT_INVALID; AUD_Reference<AUD_IReader> reader = AUD_ChannelMapperFactory(*sound, specs).createReader(); specs.specs = reader->getSpecs(); int len; float samplejump = specs.rate / samples_per_second; float min, max, power; bool eos; for(int i = 0; i < length; i++) { len = floor(samplejump * (i+1)) - floor(samplejump * i); aBuffer.assureSize(len * AUD_SAMPLE_SIZE(specs)); buf = aBuffer.getBuffer(); reader->read(len, eos, buf); max = min = *buf; power = *buf * *buf; for(int j = 1; j < len; j++) { if(buf[j] < min) min = buf[j]; if(buf[j] > max) max = buf[j]; power += buf[j] * buf[j]; } buffer[i * 3] = min; buffer[i * 3 + 1] = max; buffer[i * 3 + 2] = sqrt(power) / len; if(eos) { length = i; break; } } return length; }
AUD_Reference<AUD_IHandle> AUD_OpenALDevice::play(AUD_Reference<AUD_IReader> reader, bool keep) { AUD_Specs specs = reader->getSpecs(); // check format if(specs.channels == AUD_CHANNELS_INVALID) return AUD_Reference<AUD_IHandle>(); if(m_specs.format != AUD_FORMAT_FLOAT32) reader = new AUD_ConverterReader(reader, m_specs); ALenum format; if(!getFormat(format, specs)) return AUD_Reference<AUD_IHandle>(); lock(); alcSuspendContext(m_context); AUD_Reference<AUD_OpenALDevice::AUD_OpenALHandle> sound; try { // create the handle sound = new AUD_OpenALDevice::AUD_OpenALHandle(this, format, reader, keep); } catch(AUD_Exception&) { alcProcessContext(m_context); unlock(); throw; } alcProcessContext(m_context); // play sound m_playingSounds.push_back(sound); start(); unlock(); return AUD_Reference<AUD_IHandle>(sound); }
AUD_SRCResampleReader::AUD_SRCResampleReader(AUD_Reference<AUD_IReader> reader, AUD_Specs specs) : AUD_ResampleReader(reader, specs.rate), m_channels(reader->getSpecs().channels), m_position(0) { int error; m_src = src_callback_new(src_callback, SRC_SINC_MEDIUM_QUALITY, m_channels, &error, this); if(!m_src) { // XXX printf("%s\n", src_strerror(error)); AUD_THROW(AUD_ERROR_SRC, state_error); } }
void AUD_setSequencerDeviceSpecs(AUD_Sound* sequencer) { dynamic_cast<AUD_SequencerFactory*>(sequencer->get())->setSpecs(AUD_device->getSpecs().specs); }