diff options
author | Henri Herscher <henri@oreka.org> | 2005-10-20 13:40:58 +0000 |
---|---|---|
committer | Henri Herscher <henri@oreka.org> | 2005-10-20 13:40:58 +0000 |
commit | 7e1d63dd9fd149e4934bf77095c8610fac786b04 (patch) | |
tree | 5fe486a1b0300c3b84fb559107a868e5cc2c95da /orkaudio/audiofile | |
parent | 467768fc956fc3e5a253373f26c71c681b31b6b8 (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.cpp | 58 | ||||
-rw-r--r-- | orkaudio/audiofile/AudioFile.h | 69 | ||||
-rw-r--r-- | orkaudio/audiofile/LibSndFileFile.cpp | 123 | ||||
-rw-r--r-- | orkaudio/audiofile/LibSndFileFile.h | 46 | ||||
-rw-r--r-- | orkaudio/audiofile/Makefile.am | 6 | ||||
-rw-r--r-- | orkaudio/audiofile/PcmFile.cpp | 100 | ||||
-rw-r--r-- | orkaudio/audiofile/PcmFile.h | 41 |
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 + |