From 8bc40b2f645ebbcee4238c14f71cbc6b5e100df2 Mon Sep 17 00:00:00 2001 From: Stefan Sayer Date: Tue, 10 Jul 2007 11:19:10 +0000 Subject: [PATCH] AmAudio class that mixes in a file into an audio at regular intervals git-svn-id: http://svn.berlios.de/svnroot/repos/sems/trunk@394 8eb893ce-cfd4-0310-b710-fb5ebe64c474 --- core/AmAudioMixIn.cpp | 105 ++++++++++++++++++++++++++++++++++++++++++ core/AmAudioMixIn.h | 76 ++++++++++++++++++++++++++++++ 2 files changed, 181 insertions(+) create mode 100644 core/AmAudioMixIn.cpp create mode 100644 core/AmAudioMixIn.h diff --git a/core/AmAudioMixIn.cpp b/core/AmAudioMixIn.cpp new file mode 100644 index 00000000..14a5d74a --- /dev/null +++ b/core/AmAudioMixIn.cpp @@ -0,0 +1,105 @@ +/* + * $Id: AmAudioMixIn.cpp 322 2007-05-02 18:49:26Z sayer $ + * + * Copyright (C) 2007 iptego GmbH + * + * This file is part of sems, a free SIP media server. + * + * sems is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * For a license to use the sems software under conditions + * other than those described here, or to purchase support for this + * software, please contact iptel.org by e-mail at the following addresses: + * info@iptel.org + * + * sems is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "AmAudioMixIn.h" +#include "SampleArray.h" + +AmAudioMixIn::AmAudioMixIn(AmAudio* A, AmAudioFile* B, + unsigned int s, double l) + : A(A),B(B), s(s), l(l), mixing(false), next_start_ts_i(false) +{ +} +AmAudioMixIn::~AmAudioMixIn() { } + +int AmAudioMixIn::get(unsigned int user_ts, unsigned char* buffer, + unsigned int nb_samples) { + if (!mixing) { + if (!next_start_ts_i) { + next_start_ts_i = true; + next_start_ts = user_ts + s*DEFAULT_SAMPLE_RATE; + } else { + if (ts_less()(next_start_ts, user_ts)) { + DBG("starting mix-in\n"); + mixing = true; + next_start_ts = user_ts + s*DEFAULT_SAMPLE_RATE; + } + } + } + + if (!mixing) { + return A->get(user_ts, buffer, nb_samples); + } else { + if (l < 0.01) { // epsilon + // only play back from B + int res = B->get(user_ts, buffer, nb_samples); + if (res <= 0) { // B empty + res = A->get(user_ts, buffer, nb_samples); + mixing = false; + B->rewind(); + } + return res; + } else { // mix the two + int res = 0; + short* pdest = (short*)buffer; + // get audio from A + int len = A->get(user_ts, (unsigned char*)mix_buf, nb_samples); + + if (len<0) { // A finished + return len; + } + for (int i=0;iget(user_ts, (unsigned char*)mix_buf, nb_samples); + + if (len<0) { // B finished + mixing = false; + B->rewind(); + } else { + for (int i=0;ires) // audio from B is longer than from A + res = len; + } + return res; + } + } +} + +int AmAudioMixIn::put(unsigned int user_ts, unsigned char* buffer, unsigned int size) { + ERROR("writing not supported\n"); + return -1; +} diff --git a/core/AmAudioMixIn.h b/core/AmAudioMixIn.h new file mode 100644 index 00000000..5805fb1c --- /dev/null +++ b/core/AmAudioMixIn.h @@ -0,0 +1,76 @@ +/* + * $Id: AmAudioMixIn.h 322 2007-05-02 18:49:26Z sayer $ + * + * Copyright (C) 2007 iptego GmbH + * + * This file is part of sems, a free SIP media server. + * + * sems is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * For a license to use the sems software under conditions + * other than those described here, or to purchase support for this + * software, please contact iptel.org by e-mail at the following addresses: + * info@iptel.org + * + * sems is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _AM_AUDIO_MIX_IN_H +#define _AM_AUDIO_MIX_IN_H + +#include "AmAudio.h" + + +#define MAX_PACKETLENGTH_MS 30 +#define MAX_BUF_SAMPLES 8000 * MAX_PACKETLENGTH_MS / 1000 +#define DEFAULT_SAMPLE_RATE 8000 // eh... + +/** + * \brief \ref AmAudio to mix in every n seconds a file + * + * AmAudio that plays Audio A and + * every s seconds mixes in AudioFile B with level l. + * If l == 0, playback of A is not continued when playing B, + * which means that it continues right where it was before + * playback of B started. + * + */ +class AmAudioMixIn : public AmAudio { + AmAudio* A; + AmAudioFile* B; + unsigned int s; + double l; + + bool mixing; + + unsigned int next_start_ts; + bool next_start_ts_i; + + short mix_buf[MAX_BUF_SAMPLES]; // 240 + + public: + AmAudioMixIn(AmAudio* A, AmAudioFile* B, + unsigned int s, double l); + ~AmAudioMixIn(); + protected: + // not used + int read(unsigned int user_ts, unsigned int size){ return -1; } + int write(unsigned int user_ts, unsigned int size){ return -1; } + + // override AmAudio + int get(unsigned int user_ts, unsigned char* buffer, unsigned int nb_samples); + int put(unsigned int user_ts, unsigned char* buffer, unsigned int size); +}; + + +#endif // _AM_AUDIO_MIX_IN_H