Commit 834e835d authored by Philippe Gorley's avatar Philippe Gorley Committed by Andreas Traczyk

audio: remove sndfile dependency

Removes unused/deprecated audiorecord/audiorecorder
Allows any file to be used as a ringtone (mp3, ogg, etc)

Change-Id: I9ce33ec3d5f083caf098266befa597e78a95d7d6
parent 60305d92
This diff is collapsed.
......@@ -355,9 +355,6 @@ dnl Check for the samplerate development package - name: libsamplerate0-dev
LIBSAMPLERATE_MIN_VERSION=0.1.2
PKG_CHECK_MODULES(SAMPLERATE, samplerate >= ${LIBSAMPLERATE_MIN_VERSION},, AC_MSG_ERROR([Missing libsamplerate development files]))
dnl Check for the sndfile development package - name: libsndfile-dev
PKG_CHECK_MODULES(SNDFILE, sndfile,, AC_MSG_ERROR([Missing sndfile development files]))
dnl Coverage is default-disabled
AC_ARG_ENABLE([coverage], AS_HELP_STRING([--enable-coverage], [Enable coverage]))
......
......@@ -115,7 +115,6 @@ build\portaudio\msvc\portaudio.vcxproj, ^
build\yaml-cpp\msvc\yaml-cpp.vcxproj, ^
build\pcre\msvc\pcre.vcxproj, ^
build\libsamplerate\msvc\libsamplerate.vcxproj, ^
build\sndfile\msvc\libsndfile.vcxproj, ^
)
goto startBuild
......
......@@ -65,7 +65,6 @@ pthreads, ^
restbed, ^
samplerate, ^
secp256k1, ^
sndfile, ^
upnp, ^
vpx, ^
x264, ^
......
4ca9780ed0a915aca8a10ef91bf4bf48b05ecb85285c2c3fe7eef1d46d3e0747e61416b6bddbef369bd69adf4b796ff5f61380e0bc998906b170a93341ba6f78 libsndfile-1.0.25.tar.gz
From ca790066b639ea570067afb3cb2a36c9e3383ae8 Mon Sep 17 00:00:00 2001
From: Erik de Castro Lopo <erikd@mega-nerd.com>
Date: Sat, 13 Jul 2013 17:04:45 +1000
Subject: [PATCH] configure.ac : Fix for current versions of autotools.
Patch from Cristian Rodriguez.
---
configure.ac | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/configure.ac b/configure.ac
index bef0c18..3b32cb7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -20,7 +20,8 @@ m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
AC_LANG([C])
-AC_PROG_CC
+AC_PROG_CC_STDC
+AC_USE_SYSTEM_EXTENSIONS
AM_PROG_CC_C_O
AC_PROG_CXX
AC_PROG_SED
@@ -331,8 +332,8 @@ if test -n "$PKG_CONFIG" ; then
HAVE_EXTERNAL_LIBS=1
enable_external_libs=yes
- EXTERNAL_CFLAGS="$FLAC_CFLAGS $OGG_CFLAGS $VORBISENC_CFLAGS $SPEEX_CFLAGS"
- EXTERNAL_LIBS="$FLAC_LIBS $VORBISENC_LIBS $SPEEX_LIBS"
+ EXTERNAL_CFLAGS="$FLAC_CFLAGS $OGG_CFLAGS $VORBIS_CFLAGS $VORBISENC_CFLAGS $SPEEX_CFLAGS"
+ EXTERNAL_LIBS="$FLAC_LIBS $OGG_LIBS $VORBIS_LIBS $VORBISENC_LIBS $SPEEX_LIBS "
else
echo
AC_MSG_WARN([[*** One or more of the external libraries (ie libflac, libogg and]])
--- a/programs/sndfile-play.c.orig 2014-06-26 18:33:49.000000000 -0400
+++ b/programs/sndfile-play.c 2014-06-26 18:33:52.000000000 -0400
@@ -63,7 +63,6 @@
#include <sys/soundcard.h>
#elif (defined (__MACH__) && defined (__APPLE__))
- #include <Carbon.h>
#include <CoreAudio/AudioHardware.h>
#elif defined (HAVE_SNDIO_H)
--- a/Makefile.am 2016-05-30 11:59:21.000000000 -0400
+++ b/Makefile.am 2016-05-30 11:59:28.000000000 -0400
@@ -6,8 +6,8 @@
octave_dir = Octave
endif
-SUBDIRS = M4 man doc Win32 src $(octave_dir) examples regtest tests programs
-DIST_SUBDIRS = M4 man doc Win32 src Octave examples regtest tests programs
+SUBDIRS = M4 man doc Win32 src $(octave_dir)
+DIST_SUBDIRS = M4 man doc Win32 src Octave
EXTRA_DIST = libsndfile.spec.in sndfile.pc.in
set BUILD=%SRC%..\build
set SNDFILE_VERSION=1.0.25
set SNDFILE_URL=http://www.mega-nerd.com/libsndfile/files/libsndfile-%SNDFILE_VERSION%.tar.gz
mkdir %BUILD%
if %USE_CACHE%==1 (
copy %CACHE_DIR%\libsndfile-%SNDFILE_URL%.tar.gz %cd%
) else (
%WGET_CMD% %SNDFILE_URL%
)
7z -y x libsndfile-%SNDFILE_VERSION%.tar.gz && 7z -y x libsndfile-%SNDFILE_VERSION%.tar -o%BUILD%
del libsndfile-%SNDFILE_VERSION%.tar && del libsndfile-%SNDFILE_VERSION%.tar.gz
rename %BUILD%\libsndfile-%SNDFILE_VERSION% sndfile
cd %BUILD%\sndfile
%APPLY_CMD% %SRC%\sndfile\sndfile-vs2017.patch
cd %SRC%
\ No newline at end of file
# SNDFILE
SNDFILE_VERSION := 1.0.25
SNDFILE_URL := http://www.mega-nerd.com/libsndfile/files/libsndfile-$(SNDFILE_VERSION).tar.gz
PKGS += sndfile
ifeq ($(call need_pkg,"sndfile"),)
PKGS_FOUND += sndfile
endif
DEPS_sndfile = ogg vorbis flac
$(TARBALLS)/libsndfile-$(SNDFILE_VERSION).tar.gz:
$(call download,$(SNDFILE_URL))
.sum-sndfile: libsndfile-$(SNDFILE_VERSION).tar.gz
sndfile: libsndfile-$(SNDFILE_VERSION).tar.gz .sum-sndfile
$(UNPACK)
$(APPLY) $(SRC)/sndfile/soundcard.patch
$(APPLY) $(SRC)/sndfile/carbon.patch
$(APPLY) $(SRC)/sndfile/autotools.patch
$(APPLY) $(SRC)/sndfile/disable_programs.patch
$(UPDATE_AUTOCONFIG) && cd $(UNPACK_DIR) && mv config.guess config.sub Cfg && autoreconf -fi
ifdef HAVE_IOS
rm -Rf examples
endif
$(MOVE)
.sndfile: sndfile
cd $< && $(HOSTVARS) ./configure $(HOSTCONF)
cd $< && $(MAKE) install
touch $@
This diff is collapsed.
--- a/programs/sndfile-play.c.orig 2014-06-12 16:00:39.348060215 -0400
+++ b/programs/sndfile-play.c 2014-06-12 16:01:05.660059438 -0400
@@ -52,7 +52,12 @@
#include <sys/time.h>
#endif
-#if defined (__linux__) || defined (__FreeBSD_kernel__) || defined (__FreeBSD__)
+#if defined(__ANDROID__)
+ #include <fcntl.h>
+ #include <sys/ioctl.h>
+ #include <linux/soundcard.h>
+
+#elif defined (__linux__) || defined (__FreeBSD_kernel__) || defined (__FreeBSD__)
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/soundcard.h>
......@@ -32,7 +32,6 @@ RUN apt-get update && \
libpcre3-dev \
libyaml-cpp-dev \
libboost-dev \
libsndfile1-dev \
libxext-dev \
libxfixes-dev \
libspeex-dev \
......
......@@ -50,7 +50,6 @@ libring_la_LDFLAGS = \
@ALSA_LIBS@ \
@PULSEAUDIO_LIBS@ \
@SAMPLERATE_LIBS@ \
@SNDFILE_LIBS@ \
@YAMLCPP_LIBS@ \
@JSONCPP_LIBS@ \
@SPEEXDSP_LIBS@ \
......
......@@ -26,7 +26,6 @@
#include "audio/ringbufferpool.h"
#include "dring/call_const.h"
#include "client/ring_signal.h"
#include "audio/audiorecord.h"
#include "sip/sip_utils.h"
#include "ip_utils.h"
#include "array_size.h"
......
......@@ -25,7 +25,6 @@
#include "manager.h"
#include "audio/audiolayer.h"
#include "audio/ringbufferpool.h"
#include "audio/audiorecord.h"
#ifdef RING_VIDEO
#include "sip/sipcall.h"
......
......@@ -42,8 +42,6 @@ libaudio_la_SOURCES = \
audioloop.cpp \
ringbuffer.cpp \
ringbufferpool.cpp \
audiorecord.cpp \
audiorecorder.cpp \
audiolayer.cpp \
resampler.cpp \
$(RING_SPEEXDSP_SRC) \
......@@ -64,8 +62,6 @@ noinst_HEADERS = \
audioloop.h \
ringbuffer.h \
ringbufferpool.h \
audiorecord.h \
audiorecorder.h \
audiolayer.h \
$(RING_SPEEXDSP_HEAD) \
dcblocker.h \
......
......@@ -332,4 +332,26 @@ AudioBuffer::toAVFrame() const
return frame;
}
int
AudioBuffer::append(AVFrame* frame)
{
// FIXME we assume frame is s16 interleaved
if (channels() != static_cast<unsigned>(frame->channels)
|| getSampleRate() != frame->sample_rate) {
auto newFormat = AudioFormat{(unsigned)frame->sample_rate, (unsigned)frame->channels};
setFormat(newFormat);
}
AudioBuffer toAppend(frame->nb_samples,
{(unsigned)frame->sample_rate, (unsigned)frame->channels});
toAppend.deinterleave(reinterpret_cast<const AudioSample*>(frame->extended_data[0]),
frame->nb_samples, frame->channels);
for (size_t c = 0; c < samples_.size(); ++c) {
samples_[c].insert(samples_[c].end(), toAppend.samples_[c].begin(), toAppend.samples_[c].end());
}
return 0;
}
} // namespace ring
......@@ -347,6 +347,8 @@ class AudioBuffer {
AVFrame* toAVFrame() const;
int append(AVFrame* frame);
private:
int sampleRate_;
......
/*
* Copyright (C) 2004-2018 Savoir-faire Linux Inc.
*
* Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
* Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
*
* This program 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 3 of the License, or
* (at your option) any later version.
*
* This program 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "audiorecord.h"
#include "logger.h"
#include "fileutils.h"
#include "manager.h"
#ifndef RING_UWP
#include <sndfile.hh>
#endif
#include <algorithm>
#include <sstream> // for stringstream
#include <cstdio>
#include <unistd.h>
namespace ring {
static std::string
createFilename()
{
time_t rawtime = time(NULL);
struct tm * timeinfo = localtime(&rawtime);
std::stringstream out;
// DATE
out << timeinfo->tm_year + 1900;
if (timeinfo->tm_mon < 9) // january is 01, not 1
out << 0;
out << timeinfo->tm_mon + 1;
if (timeinfo->tm_mday < 10) // 01 02 03, not 1 2 3
out << 0;
out << timeinfo->tm_mday;
out << '-';
// hour
if (timeinfo->tm_hour < 10) // 01 02 03, not 1 2 3
out << 0;
out << timeinfo->tm_hour;
if (timeinfo->tm_min < 10) // 01 02 03, not 1 2 3
out << 0;
out << timeinfo->tm_min;
if (timeinfo->tm_sec < 10) // 01 02 03, not 1 2 3
out << 0;
out << timeinfo->tm_sec;
return out.str();
}
AudioRecord::AudioRecord()
: sndFormat_(AudioFormat::MONO())
, filename_(createFilename())
, savePath_()
, recorder_(this, Manager::instance().getRingBufferPool())
{
RING_DBG("Generate filename for this call %s ", filename_.c_str());
}
AudioRecord::~AudioRecord()
{
closeFile();
}
void AudioRecord::setSndFormat(AudioFormat format)
{
sndFormat_ = format;
}
void AudioRecord::setRecordingOptions(AudioFormat format, const std::string &path)
{
std::string filePath;
// use HOME directory if path is empty, or if path does not exist
if (path.empty() or not fileutils::check_dir(path.c_str())) {
filePath = fileutils::get_home_dir();
} else {
filePath = path;
}
sndFormat_ = format;
savePath_ = (*filePath.rbegin() == DIR_SEPARATOR_CH) ? filePath : filePath + DIR_SEPARATOR_STR;
}
static bool
nonFilenameCharacter(char c)
{
return not(std::isalnum(c) or c == '_' or c == '.');
}
// Replace any character that is inappropriate for a filename with '_'
static std::string
sanitize(std::string s)
{
std::replace_if(s.begin(), s.end(), nonFilenameCharacter, '_');
return s;
}
void AudioRecord::initFilename(const std::string &peerNumber)
{
RING_DBG("Initialize audio record for peer : %s", peerNumber.c_str());
// if savePath_ don't contains filename
if (savePath_.find(".wav") == std::string::npos) {
filename_ = createFilename();
filename_.append("-" + sanitize(peerNumber) + "-" PACKAGE);
filename_.append(".wav");
} else {
filename_ = "";
}
}
std::string AudioRecord::getPath() const
{
return savePath_ + filename_;
}
bool
AudioRecord::openFile()
{
#ifndef RING_UWP
fileHandle_.reset(); // do it before calling fileExists()
const bool doAppend = fileExists();
const int access = doAppend ? SFM_RDWR : SFM_WRITE;
RING_DBG("Opening file %s with format %s", getPath().c_str(), sndFormat_.toString().c_str());
fileHandle_.reset(new SndfileHandle (getPath().c_str(),
access,
SF_FORMAT_WAV | SF_FORMAT_PCM_16,
sndFormat_.nb_channels,
sndFormat_.sample_rate));
// check overloaded boolean operator
if (!*fileHandle_) {
RING_WARN("Could not open WAV file!");
fileHandle_.reset();
return false;
}
if (doAppend and fileHandle_->seek(0, SEEK_END) < 0)
RING_WARN("Couldn't seek to the end of the file ");
return true;
#else
return false;
#endif
}
void
AudioRecord::closeFile()
{
stopRecording(); // needed as recData accesses to fileHandle_
fileHandle_.reset();
}
bool
AudioRecord::isOpenFile() const noexcept
{
return static_cast<bool>(fileHandle_);
}
bool AudioRecord::fileExists() const
{
return access(getPath().c_str(), F_OK) != -1;
}
bool AudioRecord::isRecording() const
{
return recordingEnabled_;
}
bool
AudioRecord::toggleRecording()
{
if (isOpenFile())
recordingEnabled_ = !recordingEnabled_;
else if (openFile()) {
recordingEnabled_ = true;
recorder_.start();
}
return recordingEnabled_;
}
void
AudioRecord::stopRecording() const noexcept
{
RING_DBG("Stop recording %s", getPath().c_str());
recordingEnabled_ = false;
}
void
AudioRecord::recData(AudioBuffer& buffer)
{
#ifndef _MSC_VER
if (not recordingEnabled_)
return;
auto interleaved = buffer.interleave();
const int nSamples = interleaved.size();
if (fileHandle_->write(interleaved.data(), nSamples) != nSamples) {
RING_WARN("Could not record data!");
} else {
fileHandle_->writeSync();
}
#endif
}
} // namespace ring
/*
* Copyright (C) 2004-2018 Savoir-faire Linux Inc.
*
* Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
* Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
*
* This program 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 3 of the License, or
* (at your option) any later version.
*
* This program 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#pragma once
#include "audiobuffer.h"
#include "audiorecorder.h"
#include "noncopyable.h"
#include <atomic>
#include <memory>
#include <string>
#include <cstdlib>
class SndfileHandle;
namespace ring {
class AudioRecord {
public:
AudioRecord();
~AudioRecord();
void setSndFormat(AudioFormat format);
void setRecordingOptions(AudioFormat format, const std::string &path);
/**
* Init recording file path
*/
void initFilename(const std::string &peerNumber);
/**
* Return the file path of the recording
*/
std::string getPath() const;
/**
* Check if no other file is opened, then create a new one
* @param filename A string containing the file (with/without extension)
* @param type The sound file format (FILE_RAW, FILE_WAVE)
* @param format Internal sound format (INT16 / INT32)
* @return bool True if file was opened
*/
bool openFile();
/**
* Close the opened recording file. If wave: cout the number of byte
*/
void closeFile();
/**
* Check if a file is already opened
*/
bool isOpenFile() const noexcept;
/**
* Check if a file already exists
*/
bool fileExists() const;
/**
* Check recording state
*/
bool isRecording() const;
/**
* Toggle recording state
*/
bool toggleRecording();
/**
* Stop recording flag
*/
void stopRecording() const noexcept;
/**
* Record a chunk of data in an openend file
* @param buffer The data chunk to be recorded
* @param nSamples Number of samples (number of bytes) to be recorded
*/
void recData(AudioBuffer& buffer);
std::string getRecorderID() const {
return recorder_.getRecorderID();
}
private:
NON_COPYABLE(AudioRecord);
/**
* Open an existing raw file, used when the call is set on hold
*/
bool openExistingRawFile();
/**
* Open an existing wav file, used when the call is set on hold
*/
bool openExistingWavFile();
/**
* Compute the number of byte recorded and close the file
*/
void closeWavFile();
/**
* Pointer to the recorded file
*/
std::shared_ptr<SndfileHandle> fileHandle_;
/**
* Number of channels
*/
AudioFormat sndFormat_;
/**
* Recording flage
*/
mutable std::atomic<bool> recordingEnabled_ {false};
/**
* Filename for this recording
*/
std::string filename_;
/**
* Path for this recording
*/
std::string savePath_;
/**
* Audio recording thread
*/
AudioRecorder recorder_;
};
} // namespace ring
/*
* Copyright (C) 2004-2018 Savoir-faire Linux Inc.
*
* Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
* Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
*
* This program 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 3 of the License, or
* (at your option) any later version.
*
* This program 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "audiorecorder.h"
#include "audiorecord.h"
#include "ringbufferpool.h"
#include "audiobuffer.h"
#include <chrono>
#include <thread>
#include <sstream>
#include <algorithm> // std::min
namespace ring {
static constexpr std::size_t BUFFER_LENGTH {10000};
static constexpr auto SLEEP_TIME = std::chrono::milliseconds(20);
AudioRecorder::AudioRecorder(AudioRecord* arec, RingBufferPool& rbp)
: ringBufferPool_(rbp)
, buffer_(new AudioBuffer(BUFFER_LENGTH, AudioFormat::NONE()))
, arecord_(arec)
, thread_(
[] { return true; },
[this] { process(); },
[] {})
{
std::string id("processd_");
// convert count into string
std::string s;
std::ostringstream out;
out << nextProcessID();
s = out.str();
recorderId_ = id.append(s);
}
AudioRecorder::~AudioRecorder()
{
thread_.join();
}
unsigned
AudioRecorder::nextProcessID() noexcept
{
static unsigned id = 0;
return ++id;
}
void
AudioRecorder::start()
{
if (thread_.isRunning())
return;
buffer_->setFormat(ringBufferPool_.getInternalAudioFormat());
thread_.start();
}
void
AudioRecorder::process()
{
auto availableSamples = ringBufferPool_.availableForGet(recorderId_);
buffer_->resize(std::min(availableSamples, BUFFER_LENGTH));
ringBufferPool_.getData(*buffer_, recorderId_);
if (availableSamples > 0)
arecord_->recData(*buffer_);