summaryrefslogtreecommitdiff
path: root/orkaudio/audiofile
diff options
context:
space:
mode:
authorHenri Herscher <henri@oreka.org>2005-10-20 13:40:58 +0000
committerHenri Herscher <henri@oreka.org>2005-10-20 13:40:58 +0000
commit7e1d63dd9fd149e4934bf77095c8610fac786b04 (patch)
tree5fe486a1b0300c3b84fb559107a868e5cc2c95da /orkaudio/audiofile
parent467768fc956fc3e5a253373f26c71c681b31b6b8 (diff)
First checkin
git-svn-id: https://oreka.svn.sourceforge.net/svnroot/oreka/trunk@2 09dcff7a-b715-0410-9601-b79a96267cd0
Diffstat (limited to 'orkaudio/audiofile')
-rw-r--r--orkaudio/audiofile/AudioFile.cpp58
-rw-r--r--orkaudio/audiofile/AudioFile.h69
-rw-r--r--orkaudio/audiofile/LibSndFileFile.cpp123
-rw-r--r--orkaudio/audiofile/LibSndFileFile.h46
-rw-r--r--orkaudio/audiofile/Makefile.am6
-rw-r--r--orkaudio/audiofile/PcmFile.cpp100
-rw-r--r--orkaudio/audiofile/PcmFile.h41
7 files changed, 443 insertions, 0 deletions
diff --git a/orkaudio/audiofile/AudioFile.cpp b/orkaudio/audiofile/AudioFile.cpp
new file mode 100644
index 0000000..377963b
--- /dev/null
+++ b/orkaudio/audiofile/AudioFile.cpp
@@ -0,0 +1,58 @@
+/*
+ * Oreka -- A media capture and retrieval platform
+ *
+ * Copyright (C) 2005, orecx LLC
+ *
+ * http://www.orecx.com
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License.
+ * Please refer to http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "AudioFile.h"
+#include "ace/OS_NS_unistd.h"
+
+void AudioFile::Open(fileOpenModeEnum mode, bool stereo , int sampleRate)
+{
+ Open(m_filename, mode, stereo, sampleRate);
+}
+
+
+void AudioFile::RecursiveMkdir(CStdString& path)
+{
+ int position = 0;
+ bool done = false;
+ while (!done)
+ {
+ position = path.Find('/', position+1);
+ if (position == -1)
+ {
+ done = true;
+ }
+ else
+ {
+ CStdString level = path.Left(position);
+ ACE_OS::mkdir((PCSTR)level);
+ }
+ }
+}
+
+void AudioFile::MoveOrig()
+{
+ CStdString newName = m_filename + ".orig";
+ if (ACE_OS::rename((PCSTR)m_filename, (PCSTR)newName) == 0)
+ {
+ m_filename = newName;
+ }
+ else
+ {
+ throw(CStdString("AudioFile::MoveOrig: could not rename file:" + m_filename));
+ }
+}
+
+void AudioFile::Delete()
+{
+ ACE_OS::unlink((PCSTR)m_filename);
+}
diff --git a/orkaudio/audiofile/AudioFile.h b/orkaudio/audiofile/AudioFile.h
new file mode 100644
index 0000000..cd7d6f6
--- /dev/null
+++ b/orkaudio/audiofile/AudioFile.h
@@ -0,0 +1,69 @@
+/*
+ * Oreka -- A media capture and retrieval platform
+ *
+ * Copyright (C) 2005, orecx LLC
+ *
+ * http://www.orecx.com
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License.
+ * Please refer to http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#ifndef __AUDIOFILE_H__
+#define __AUDIOFILE_H__
+
+#include "boost/shared_ptr.hpp"
+#include "ace/OS_NS_stdio.h"
+#include "ace/OS_NS_sys_stat.h"
+
+#include "StdString.h"
+#include "AudioCapture.h"
+
+
+/** Base class for all file accessor classes. */
+class AudioFile
+{
+public:
+ typedef enum {READ = 0, WRITE = 1} fileOpenModeEnum;
+
+ /** Open audio file for reading or writing.
+ Filename should include path information but not extension (which is automatically appended)
+ If the underlying format does not support stereo, data is transparently read from two files in read mode
+ or two files are transparently written to in write mode */
+ virtual void Open(CStdString& filename, fileOpenModeEnum mode, bool stereo = false, int sampleRate = 8000) = 0;
+ /** Same as above but uses the intenal filename */
+ void Open(fileOpenModeEnum mode, bool stereo = false, int sampleRate = 8000);
+ /** Explicitely close the underlying file(s). This is also done automatically by the destructor */
+ virtual void Close() = 0;
+
+ /** Writes a chunk of audio to disk.
+ If stereo capture, this represents the local party */
+ virtual void WriteChunk(AudioChunkRef chunkRef) = 0;
+ /** Writes a chunk of audio from the remote pary to disk (if stereo capture)
+ //virtual bool WriteRemoteChunk(AudioChunkRef chunkRef) = 0;
+ /** Reads a chunk of audio stereo-wise
+ If underlying storage is mono, remoteChunk will be NULL
+ ReadChunkStereo guarantees that local and remote chunks returned are in sync */
+ //virtual bool ReadChunkStereo(AudioChunkRef& chunk, AudioChunkRef& remoteChunk) = 0;
+ /** Reads a chunk of audio mono-wise
+ If underlying file is stereo, ReadChunkMono merges the two streams in a synchronized manner and returns the result */
+ virtual int ReadChunkMono(AudioChunkRef& chunk) = 0;
+
+ /** Move the file to a new name including ".orig" suffix */
+ void MoveOrig();
+ void Delete();
+ virtual CStdString GetExtension() = 0;
+
+ static void RecursiveMkdir(CStdString& path);
+protected:
+ CStdString m_filename;
+ fileOpenModeEnum m_mode;
+ int m_numChunksWritten;
+};
+
+typedef boost::shared_ptr<AudioFile> AudioFileRef;
+
+#endif
+
diff --git a/orkaudio/audiofile/LibSndFileFile.cpp b/orkaudio/audiofile/LibSndFileFile.cpp
new file mode 100644
index 0000000..cc5bf82
--- /dev/null
+++ b/orkaudio/audiofile/LibSndFileFile.cpp
@@ -0,0 +1,123 @@
+/*
+ * Oreka -- A media capture and retrieval platform
+ *
+ * Copyright (C) 2005, orecx LLC
+ *
+ * http://www.orecx.com
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License.
+ * Please refer to http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#define _WINSOCKAPI_ // prevents the inclusion of winsock.h
+
+#include "Utils.h"
+#include "LibSndFileFile.h"
+
+LibSndFileFile::LibSndFileFile(int fileFormat)
+{
+ m_fileInfo.format = fileFormat;
+ m_fileInfo.frames = 0;
+ m_fileInfo.samplerate = 0;
+ m_fileInfo.channels = 0;
+ m_fileInfo.sections = 0;
+ m_fileInfo.seekable = 0;
+ m_pFile = NULL;
+ m_numChunksWritten = 0;
+ m_mode = READ;
+}
+
+LibSndFileFile::~LibSndFileFile()
+{
+ Close();
+}
+
+void LibSndFileFile::Open(CStdString& filename, fileOpenModeEnum mode, bool stereo, int sampleRate)
+{
+ if(!m_filename.Equals(filename))
+ {
+ m_filename = filename + ".wav";
+ }
+ m_mode = mode;
+ stereo ? m_fileInfo.channels = 2 : m_fileInfo.channels = 1;
+ m_fileInfo.samplerate = sampleRate;
+
+ if( (mode==WRITE) && !sf_format_check(&m_fileInfo))
+ {
+ throw(CStdString("libsndfile: Selected output format not supported"));
+ }
+
+ RecursiveMkdir(m_filename);
+
+ int sndFileMode;
+ mode == READ ? sndFileMode = SFM_READ : sndFileMode = SFM_WRITE;
+ m_pFile = sf_open((PCSTR)m_filename, sndFileMode, &m_fileInfo);
+
+ if(!m_pFile)
+ {
+ throw(CStdString("sf_open failed, audio file could not be created:"+ m_filename));
+ }
+}
+
+void LibSndFileFile::WriteChunk(AudioChunkRef chunkRef)
+{
+ if (m_pFile)
+ {
+
+ if( chunkRef->m_encoding == AudioChunk::AlawAudio || chunkRef->m_encoding == AudioChunk::UlawAudio)
+ {
+ if(sf_write_raw(m_pFile, chunkRef->m_pBuffer, chunkRef->GetNumSamples()) != chunkRef->GetNumSamples())
+ {
+ CStdString numChunksWrittenString = IntToString(m_numChunksWritten);
+ throw(CStdString("sf_write_raw failed, audio file " + m_filename + " could not be written after " + numChunksWrittenString + " chunks written"));
+ }
+ }
+ else if (chunkRef->m_encoding == AudioChunk::PcmAudio)
+ {
+ if(sf_write_short(m_pFile, (short*)chunkRef->m_pBuffer, chunkRef->GetNumSamples()) != chunkRef->GetNumSamples())
+ {
+ CStdString numChunksWrittenString = IntToString(m_numChunksWritten);
+ throw(CStdString("sf_write_short failed, audio file " + m_filename + " could not be written after " + numChunksWrittenString + " chunks written"));
+ }
+ }
+ m_numChunksWritten++;
+ }
+ else
+ {
+ throw(CStdString("Write attempt on unopened file:")+ m_filename);
+ }
+}
+
+int LibSndFileFile::ReadChunkMono(AudioChunkRef& chunk)
+{
+ unsigned int numRead = 0;
+ if (m_pFile)
+ {
+ chunk.reset(new AudioChunk());
+ short temp[8000];
+ numRead = sf_read_short(m_pFile, temp, 8000);
+ chunk->SetBuffer(temp, sizeof(short)*numRead, AudioChunk::PcmAudio);
+ }
+ else
+ {
+ throw(CStdString("Read attempt on unopened file:")+ m_filename);
+ }
+ return numRead;
+}
+
+
+void LibSndFileFile::Close()
+{
+ if (m_pFile)
+ {
+ sf_close(m_pFile);
+ m_pFile = NULL;
+ }
+}
+
+CStdString LibSndFileFile::GetExtension()
+{
+ return ".wav";
+}
diff --git a/orkaudio/audiofile/LibSndFileFile.h b/orkaudio/audiofile/LibSndFileFile.h
new file mode 100644
index 0000000..e0516a8
--- /dev/null
+++ b/orkaudio/audiofile/LibSndFileFile.h
@@ -0,0 +1,46 @@
+/*
+ * Oreka -- A media capture and retrieval platform
+ *
+ * Copyright (C) 2005, orecx LLC
+ *
+ * http://www.orecx.com
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License.
+ * Please refer to http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#ifndef __LIBSNDFILEFILE_H__
+#define __LIBSNDFILEFILE_H__
+
+
+#include "StdString.h"
+#include "AudioCapture.h"
+#include "sndfile.h"
+#include "AudioFile.h"
+
+
+/** file accessor class for all file types supported by the libsndfile library.
+ The library can be found at http://www.mega-nerd.com/libsndfile/
+*/
+class LibSndFileFile : public AudioFile
+{
+public:
+ LibSndFileFile(int fileFormat); // fileFormat is described at http://www.mega-nerd.com/libsndfile/api.html
+ ~LibSndFileFile();
+
+ void Open(CStdString& filename, fileOpenModeEnum mode, bool stereo = false, int sampleRate = 8000);
+ void Close();
+
+ void WriteChunk(AudioChunkRef chunkRef);
+ int ReadChunkMono(AudioChunkRef& chunk);
+
+ CStdString GetExtension();
+private:
+ SF_INFO m_fileInfo;
+ SNDFILE* m_pFile;
+};
+
+#endif
+
diff --git a/orkaudio/audiofile/Makefile.am b/orkaudio/audiofile/Makefile.am
new file mode 100644
index 0000000..d6bddad
--- /dev/null
+++ b/orkaudio/audiofile/Makefile.am
@@ -0,0 +1,6 @@
+METASOURCES = AUTO
+noinst_LTLIBRARIES = libaudiofile.la
+libaudiofile_la_SOURCES = AudioFile.cpp LibSndFileFile.cpp PcmFile.cpp
+AM_CPPFLAGS = -D_REENTRANT
+libaudiofile_la_LIBADD =
+INCLUDES = -I@top_srcdir@ -I../../orkbasecxx
diff --git a/orkaudio/audiofile/PcmFile.cpp b/orkaudio/audiofile/PcmFile.cpp
new file mode 100644
index 0000000..93f4743
--- /dev/null
+++ b/orkaudio/audiofile/PcmFile.cpp
@@ -0,0 +1,100 @@
+/*
+ * Oreka -- A media capture and retrieval platform
+ *
+ * Copyright (C) 2005, orecx LLC
+ *
+ * http://www.orecx.com
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License.
+ * Please refer to http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "PcmFile.h"
+
+PcmFile::PcmFile()
+{
+ m_stream = NULL;
+ m_mode = READ;
+ m_numChunksWritten = 0;
+}
+
+PcmFile::~PcmFile()
+{
+ Close();
+}
+
+
+void PcmFile::Close()
+{
+ if(m_stream)
+ {
+ ACE_OS::fclose(m_stream);
+ m_stream = NULL;
+ }
+}
+
+void PcmFile::WriteChunk(AudioChunkRef chunkRef)
+{
+ unsigned int numWritten = 0;
+ if (m_stream)
+ {
+ numWritten = ACE_OS::fwrite(chunkRef->m_pBuffer, sizeof(short), chunkRef->GetNumSamples(), m_stream);
+ }
+ else
+ {
+ throw(CStdString("Write attempt on unopened file:")+ m_filename);
+ }
+
+ if (numWritten != chunkRef->GetNumSamples())
+ {
+ throw(CStdString("Could not write to file:")+ m_filename);
+ }
+}
+
+int PcmFile::ReadChunkMono(AudioChunkRef& chunkRef)
+{
+ unsigned int numRead = 0;
+ if (m_stream)
+ {
+ chunkRef.reset(new AudioChunk());
+ short temp[PCM_FILE_DEFAULT_CHUNK_NUM_SAMPLES];
+ numRead = ACE_OS::fread(temp, sizeof(short), PCM_FILE_DEFAULT_CHUNK_NUM_SAMPLES, m_stream);
+ chunkRef->SetBuffer(temp, sizeof(short)*numRead, AudioChunk::PcmAudio);
+ }
+ else
+ {
+ throw(CStdString("Read attempt on unopened file:")+ m_filename);
+ }
+ return numRead;
+}
+
+
+void PcmFile::Open(CStdString& filename, fileOpenModeEnum mode, bool stereo, int sampleRate)
+{
+ if(!m_filename.Equals(filename))
+ {
+ m_filename = filename + ".pcm";
+ }
+ m_stream = NULL;
+ m_mode = mode;
+ if (mode == READ)
+ {
+ m_stream = ACE_OS::fopen((PCSTR)m_filename, "rb");
+ }
+ else
+ {
+ RecursiveMkdir(m_filename);
+ m_stream = ACE_OS::fopen((PCSTR)m_filename, "wb");
+ }
+ if(!m_stream)
+ {
+ throw(CStdString("Could not open file: ") + m_filename);
+ }
+}
+
+CStdString PcmFile::GetExtension()
+{
+ return ".pcm";
+}
diff --git a/orkaudio/audiofile/PcmFile.h b/orkaudio/audiofile/PcmFile.h
new file mode 100644
index 0000000..91c1325
--- /dev/null
+++ b/orkaudio/audiofile/PcmFile.h
@@ -0,0 +1,41 @@
+/*
+ * Oreka -- A media capture and retrieval platform
+ *
+ * Copyright (C) 2005, orecx LLC
+ *
+ * http://www.orecx.com
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License.
+ * Please refer to http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#ifndef __PCMFILE_H__
+#define __PCMFILE_H__
+
+#include "audiofile/AudioFile.h"
+
+#define PCM_FILE_DEFAULT_CHUNK_NUM_SAMPLES 8000
+
+/** File class for raw 16 bit signed PCM output */
+class PcmFile : public AudioFile
+{
+public:
+ PcmFile();
+ ~PcmFile();
+
+ void Open(CStdString& filename, fileOpenModeEnum mode, bool stereo = false, int sampleRate = 8000);
+ void Close();
+
+ void WriteChunk(AudioChunkRef chunkRef);
+ int ReadChunkMono(AudioChunkRef& chunkRef);
+
+ CStdString GetExtension();
+protected:
+
+ FILE* m_stream;
+};
+
+#endif
+