diff options
author | Henri Herscher <henri@oreka.org> | 2006-01-20 22:38:18 +0000 |
---|---|---|
committer | Henri Herscher <henri@oreka.org> | 2006-01-20 22:38:18 +0000 |
commit | e07f34274b8912f773993ed96624242115440a3b (patch) | |
tree | 6b2f35398ceb7ff5c6a5afc9991f9a3670cb3a27 /orkaudio/audiofile | |
parent | 4ab4f3d3b2f0c3c51922eaeea49df162a9c892cd (diff) |
VoIP mixing and decoding does now happen in the batch processing thread instead of immediately. Additionally, the system now supports filter plugins such as codecs.
git-svn-id: https://oreka.svn.sourceforge.net/svnroot/oreka/trunk@120 09dcff7a-b715-0410-9601-b79a96267cd0
Diffstat (limited to 'orkaudio/audiofile')
-rw-r--r-- | orkaudio/audiofile/LibSndFileFile.cpp | 18 | ||||
-rw-r--r-- | orkaudio/audiofile/MediaChunkFile.cpp | 154 | ||||
-rw-r--r-- | orkaudio/audiofile/MediaChunkFile.h | 40 | ||||
-rw-r--r-- | orkaudio/audiofile/PcmFile.cpp | 13 |
4 files changed, 220 insertions, 5 deletions
diff --git a/orkaudio/audiofile/LibSndFileFile.cpp b/orkaudio/audiofile/LibSndFileFile.cpp index fbbf3cb..0589466 100644 --- a/orkaudio/audiofile/LibSndFileFile.cpp +++ b/orkaudio/audiofile/LibSndFileFile.cpp @@ -68,10 +68,18 @@ void LibSndFileFile::Open(CStdString& filename, fileOpenModeEnum mode, bool ster void LibSndFileFile::WriteChunk(AudioChunkRef chunkRef) { - if (m_pFile) + if(chunkRef.get() == NULL) + { + return; + } + if(chunkRef->GetDetails()->m_numBytes == 0) { + return; + } - if( chunkRef->m_encoding == AudioChunk::AlawAudio || chunkRef->m_encoding == AudioChunk::UlawAudio) + if (m_pFile) + { + if( chunkRef->GetEncoding() == AlawAudio || chunkRef->GetEncoding() == UlawAudio) { if(sf_write_raw(m_pFile, chunkRef->m_pBuffer, chunkRef->GetNumSamples()) != chunkRef->GetNumSamples()) { @@ -79,7 +87,7 @@ void LibSndFileFile::WriteChunk(AudioChunkRef chunkRef) 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) + else if (chunkRef->GetEncoding() == PcmAudio) { if(sf_write_short(m_pFile, (short*)chunkRef->m_pBuffer, chunkRef->GetNumSamples()) != chunkRef->GetNumSamples()) { @@ -103,7 +111,9 @@ int LibSndFileFile::ReadChunkMono(AudioChunkRef& chunk) chunk.reset(new AudioChunk()); short temp[8000]; numRead = sf_read_short(m_pFile, temp, 8000); - chunk->SetBuffer(temp, sizeof(short)*numRead, AudioChunk::PcmAudio, 0, 0, m_sampleRate); + AudioChunkDetails details; + details.m_encoding = PcmAudio; + chunk->SetBuffer(temp, sizeof(short)*numRead, details); } else { diff --git a/orkaudio/audiofile/MediaChunkFile.cpp b/orkaudio/audiofile/MediaChunkFile.cpp new file mode 100644 index 0000000..47b2e8b --- /dev/null +++ b/orkaudio/audiofile/MediaChunkFile.cpp @@ -0,0 +1,154 @@ +/* + * 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 "MediaChunkFile.h" + +#define MAX_CHUNK_SIZE 100000 + + +MediaChunkFile::MediaChunkFile() +{ + m_stream = NULL; + m_mode = READ; + m_numChunksWritten = 0; + m_sampleRate = 0; +} + +MediaChunkFile::~MediaChunkFile() +{ + Close(); +} + + +void MediaChunkFile::Close() +{ + if(m_stream) + { + ACE_OS::fclose(m_stream); + m_stream = NULL; + } +} + +void MediaChunkFile::WriteChunk(AudioChunkRef chunkRef) +{ + if(chunkRef.get() == NULL) + { + return; + } + if(chunkRef->GetDetails()->m_numBytes == 0) + { + return; + } + + unsigned int numWritten = 0; + bool writeError = false; + if (m_stream) + { + int tmp = sizeof(AudioChunkDetails); + numWritten = ACE_OS::fwrite(chunkRef->GetDetails(), sizeof(AudioChunkDetails), 1, m_stream); + if(numWritten != 1) + { + writeError = true; + } + numWritten = ACE_OS::fwrite(chunkRef->m_pBuffer, sizeof(char), chunkRef->GetNumBytes(), m_stream); + if(numWritten != chunkRef->GetNumBytes()) + { + writeError = true; + } + } + else + { + throw(CStdString("Write attempt on unopened file:")+ m_filename); + } + + if (writeError) + { + throw(CStdString("Could not write to file:")+ m_filename); + } +} + +int MediaChunkFile::ReadChunkMono(AudioChunkRef& chunkRef) +{ + unsigned int numRead = 0; + bool readError = false; + + if (m_stream) + { + chunkRef.reset(new AudioChunk()); + short temp[MAX_CHUNK_SIZE]; + numRead = ACE_OS::fread(temp, sizeof(AudioChunkDetails), 1, m_stream); + if(numRead == 1) + { + AudioChunkDetails details; + memcpy(&details, temp, sizeof(AudioChunkDetails)); + + if(details.m_marker != MEDIA_CHUNK_MARKER) + { + throw(CStdString("Invalid marker in file:")+ m_filename); + } + if(details.m_numBytes >= MAX_CHUNK_SIZE) + { + throw(CStdString("Chunk too big in file:")+ m_filename); + } + else + { + numRead = ACE_OS::fread(temp, sizeof(char), details.m_numBytes, m_stream); + if(numRead != details.m_numBytes) + { + throw(CStdString("Incomplete chunk in file:")+ m_filename); + } + chunkRef->SetBuffer(temp, details.m_numBytes, details); + } + } + } + else + { + throw(CStdString("Read attempt on unopened file:")+ m_filename); + } + + return numRead; +} + + +void MediaChunkFile::Open(CStdString& filename, fileOpenModeEnum mode, bool stereo, int sampleRate) +{ + if(m_sampleRate == 0) + { + m_sampleRate = sampleRate; + } + + if(!m_filename.Equals(filename)) + { + m_filename = filename + GetExtension(); + } + 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 MediaChunkFile::GetExtension() +{ + return ".mcf"; +} diff --git a/orkaudio/audiofile/MediaChunkFile.h b/orkaudio/audiofile/MediaChunkFile.h new file mode 100644 index 0000000..b8e69ed --- /dev/null +++ b/orkaudio/audiofile/MediaChunkFile.h @@ -0,0 +1,40 @@ +/* + * 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 __MEDIACHUNKFILE_H__ +#define __MEDIACHUNKFILE_H__ + +#include "audiofile/AudioFile.h" + + +/** File class for saving audio chunks as-is */ +class MediaChunkFile : public AudioFile +{ +public: + MediaChunkFile(); + ~MediaChunkFile(); + + 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 + diff --git a/orkaudio/audiofile/PcmFile.cpp b/orkaudio/audiofile/PcmFile.cpp index 0acfb3f..9d1a6d0 100644 --- a/orkaudio/audiofile/PcmFile.cpp +++ b/orkaudio/audiofile/PcmFile.cpp @@ -38,6 +38,15 @@ void PcmFile::Close() void PcmFile::WriteChunk(AudioChunkRef chunkRef) { + if(chunkRef.get() == NULL) + { + return; + } + if(chunkRef->GetDetails()->m_numBytes == 0) + { + return; + } + unsigned int numWritten = 0; if (m_stream) { @@ -62,7 +71,9 @@ int PcmFile::ReadChunkMono(AudioChunkRef& chunkRef) 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, 0, 0, m_sampleRate); + AudioChunkDetails details; + details.m_encoding = PcmAudio; + chunkRef->SetBuffer(temp, sizeof(short)*numRead, details); } else { |