00001 #include <cstdio>
00002 #include <cstdlib>
00003 #include <fcntl.h>
00004 #include <sys/time.h>
00005 #include <unistd.h>
00006 #include <time.h>
00007 #ifndef USING_MINGW
00008 #include <sys/ioctl.h>
00009 #else
00010 #include "compat.h"
00011 #endif
00012 #include <cerrno>
00013 #include <cstring>
00014 #include <iostream>
00015
00016 #include "config.h"
00017
00018 using namespace std;
00019
00020 #include "mythlogging.h"
00021 #include "audiooutputnull.h"
00022
00023 #define CHANNELS_MIN 1
00024 #define CHANNELS_MAX 8
00025
00026 AudioOutputNULL::AudioOutputNULL(const AudioSettings &settings) :
00027 AudioOutputBase(settings),
00028 pcm_output_buffer_mutex(QMutex::NonRecursive),
00029 current_buffer_size(0)
00030 {
00031 memset(pcm_output_buffer, 0, sizeof(char) * NULLAUDIO_OUTPUT_BUFFER_SIZE);
00032 InitSettings(settings);
00033 if (settings.init)
00034 Reconfigure(settings);
00035 }
00036
00037 AudioOutputNULL::~AudioOutputNULL()
00038 {
00039 KillAudio();
00040 }
00041
00042 bool AudioOutputNULL::OpenDevice()
00043 {
00044 LOG(VB_GENERAL, LOG_INFO, "Opening NULL audio device, will fail.");
00045
00046 fragment_size = NULLAUDIO_OUTPUT_BUFFER_SIZE / 2;
00047 soundcard_buffer_size = NULLAUDIO_OUTPUT_BUFFER_SIZE;
00048
00049 return false;
00050 }
00051
00052 void AudioOutputNULL::CloseDevice()
00053 {
00054 }
00055
00056 AudioOutputSettings* AudioOutputNULL::GetOutputSettings(bool )
00057 {
00058
00059 AudioFormat fmt;
00060 int rate;
00061 AudioOutputSettings *settings = new AudioOutputSettings();
00062
00063 while ((rate = settings->GetNextRate()))
00064 {
00065 settings->AddSupportedRate(rate);
00066 }
00067
00068 while ((fmt = settings->GetNextFormat()))
00069 {
00070 settings->AddSupportedFormat(fmt);
00071 }
00072
00073 for (uint channels = CHANNELS_MIN; channels <= CHANNELS_MAX; channels++)
00074 {
00075 settings->AddSupportedChannels(channels);
00076 }
00077
00078 settings->setPassthrough(-1);
00079
00080 return settings;
00081 }
00082
00083
00084 void AudioOutputNULL::WriteAudio(unsigned char* aubuf, int size)
00085 {
00086 if (buffer_output_data_for_use)
00087 {
00088 if (size + current_buffer_size > NULLAUDIO_OUTPUT_BUFFER_SIZE)
00089 {
00090 LOG(VB_GENERAL, LOG_ERR, "null audio output should not have just "
00091 "had data written to it");
00092 return;
00093 }
00094 pcm_output_buffer_mutex.lock();
00095 memcpy(pcm_output_buffer + current_buffer_size, aubuf, size);
00096 current_buffer_size += size;
00097 pcm_output_buffer_mutex.unlock();
00098 }
00099 }
00100
00101 int AudioOutputNULL::readOutputData(unsigned char *read_buffer, int max_length)
00102 {
00103 int amount_to_read = max_length;
00104 if (amount_to_read > current_buffer_size)
00105 {
00106 amount_to_read = current_buffer_size;
00107 }
00108
00109 pcm_output_buffer_mutex.lock();
00110 memcpy(read_buffer, pcm_output_buffer, amount_to_read);
00111 memmove(pcm_output_buffer, pcm_output_buffer + amount_to_read,
00112 current_buffer_size - amount_to_read);
00113 current_buffer_size -= amount_to_read;
00114 pcm_output_buffer_mutex.unlock();
00115
00116 return amount_to_read;
00117 }
00118
00119 void AudioOutputNULL::Reset()
00120 {
00121 if (buffer_output_data_for_use)
00122 {
00123 pcm_output_buffer_mutex.lock();
00124 current_buffer_size = 0;
00125 pcm_output_buffer_mutex.unlock();
00126 }
00127 AudioOutputBase::Reset();
00128 }
00129
00130 int AudioOutputNULL::GetBufferedOnSoundcard(void) const
00131 {
00132 if (buffer_output_data_for_use)
00133 {
00134 return current_buffer_size;
00135 }
00136
00137 return 0;
00138 }