Download this file

fiforeader.cpp    113 lines (97 with data), 3.4 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
/* Copyright (C) 2015 J.F.Dockes
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "fiforeader.h"
#include <iostream>
#include <string>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include "log.h"
#include "audioutil.h"
using namespace std;
FifoReader::FifoReader(const string& fn, int sampleRate, int bitsPerSample,
int chans, bool needswap, bool blocking)
: m_fn(fn), m_needswap(needswap), m_blocking(blocking),
m_fd(-1), m_tmpbuf(0), m_tmpbufsize(0)
{
setAudioParams(sampleRate, bitsPerSample, chans);
}
FifoReader::~FifoReader()
{
if (m_fn.compare("stdin") && m_fd >= 0)
::close(m_fd);
if (m_tmpbuf)
free(m_tmpbuf);
}
bool FifoReader::open()
{
LOGDEB("FifoReader::open: blocking: " << m_blocking << endl);
if (m_fn.compare("stdin")) {
int flags = m_blocking ? O_RDONLY : O_RDONLY|O_NONBLOCK;
if ((m_fd = ::open(m_fn.c_str(), flags)) < 0) {
LOGERR("open() errno " << errno << " on " << m_fn << endl);
return false;
}
} else {
m_fd = 0;
if (!m_blocking) {
fcntl(m_fd, F_SETFL, O_NONBLOCK);
}
}
return true;
}
const unsigned char *FifoReader::data(size_t size, ssize_t &nread)
{
nread = 0;
//LOGDEB("FifoReader: data " << size << " bytes. blocking " << m_blocking
// << endl);
if (m_tmpbufsize < size) {
m_tmpbuf = (unsigned char *)realloc(m_tmpbuf, size);
m_tmpbufsize = size;
}
if (m_blocking) {
size_t remaining = size;
while (remaining) {
ssize_t nread = read(m_fd, m_tmpbuf + size - remaining, remaining);
if (nread <= 0) {
LOGERR("FifoReader::read: ret " << nread << " errno " <<
errno << " : " << strerror(errno) << endl);
return 0;
} else {
remaining -= nread;
}
}
} else {
nread = read(m_fd, m_tmpbuf, size);
if (nread == -1) {
if (errno == EAGAIN)
return m_tmpbuf;
LOGERR("FifoReader::read: ret " << nread << " errno " <<
errno << " : " << strerror(errno) << endl);
return 0;
} else if (size - (size_t)nread > 0) {
LOGDEB("FifoReader::data: inserting " << size - nread <<
" bytes\n");
memset(m_tmpbuf + nread, 0, size - nread);
}
}
if (m_needswap)
swapSamples(m_tmpbuf, bytesPerSample(), m_tmpbufsize / bytesPerSample());
//LOGDEB("FifoReader: data done" << endl);
return m_tmpbuf;
}