summaryrefslogtreecommitdiff
path: root/orkaudio/audiofile
diff options
context:
space:
mode:
authorHenri Herscher <henri@oreka.org>2006-01-20 22:38:18 +0000
committerHenri Herscher <henri@oreka.org>2006-01-20 22:38:18 +0000
commite07f34274b8912f773993ed96624242115440a3b (patch)
tree6b2f35398ceb7ff5c6a5afc9991f9a3670cb3a27 /orkaudio/audiofile
parent4ab4f3d3b2f0c3c51922eaeea49df162a9c892cd (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.cpp18
-rw-r--r--orkaudio/audiofile/MediaChunkFile.cpp154
-rw-r--r--orkaudio/audiofile/MediaChunkFile.h40
-rw-r--r--orkaudio/audiofile/PcmFile.cpp13
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
{