blob: 5c8ba6e9470c32a89abb114ac155127e9ab7fa04 [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <errno.h>
#include <fcntl.h>
#include <zircon/assert.h>
#include <fbl/auto_call.h>
#include <fbl/algorithm.h>
#include <fdio/io.h>
#include <stdio.h>
#include "wav-source.h"
constexpr uint32_t WAVCommon::RIFF_FOUR_CC;
constexpr uint32_t WAVCommon::WAVE_FOUR_CC;
constexpr uint32_t WAVCommon::FMT_FOUR_CC;
constexpr uint32_t WAVCommon::DATA_FOUR_CC;
constexpr uint16_t WAVCommon::FORMAT_UNKNOWN;
constexpr uint16_t WAVCommon::FORMAT_LPCM;
constexpr uint16_t WAVCommon::FORMAT_MSFT_ADPCM;
constexpr uint16_t WAVCommon::FORMAT_IEEE_FLOAT;
constexpr uint16_t WAVCommon::FORMAT_MSFT_ALAW;
constexpr uint16_t WAVCommon::FORMAT_MSFT_MULAW;
zx_status_t WAVCommon::Initialize(const char* filename, InitMode mode) {
if (fd_ >= 0) {
printf("Failed to initialize WAVCommon for \"%s\", already initialized\n", filename);
return ZX_ERR_BAD_STATE;
}
int flags = (mode == InitMode::SOURCE)
? O_RDONLY
: O_RDWR | O_CREAT;
fd_ = ::open(filename, flags);
if (fd_ < 0) {
printf("Failed to open \"%s\" (res %d)\n", filename, fd_);
return static_cast<zx_status_t>(fd_);
}
return ZX_OK;
}
void WAVCommon::Close() {
if (fd_ >= 0) {
::close(fd_);
fd_ = -1;
}
}
zx_status_t WAVCommon::Read(void* buf, size_t len) {
if (fd_ < 0) return ZX_ERR_BAD_STATE;
ssize_t res = ::read(fd_, buf, len);
if (res < 0) {
printf("Read error (errno %d)\n", errno);
return static_cast<zx_status_t>(errno);
}
if (static_cast<size_t>(res) != len) {
printf("Short read error (%zd < %zu)\n", res, len);
return ZX_ERR_IO;
}
return ZX_OK;
}
zx_status_t WAVCommon::Write(const void* buf, size_t len) {
if (fd_ < 0) return ZX_ERR_BAD_STATE;
ssize_t res = ::write(fd_, buf, len);
if (res < 0) {
printf("Write error (errno %d)\n", errno);
return static_cast<zx_status_t>(errno);
}
if (static_cast<size_t>(res) != len) {
printf("Short write error (%zd < %zu)\n", res, len);
return ZX_ERR_IO;
}
return ZX_OK;
}
zx_status_t WAVCommon::Seek(off_t abs_pos) {
if (fd_ < 0) return ZX_ERR_BAD_STATE;
if (abs_pos < 0) return ZX_ERR_INVALID_ARGS;
off_t res = ::lseek(fd_, abs_pos, SEEK_SET);
if (res < 0) {
printf("Seek error (errno %d)\n", errno);
return static_cast<zx_status_t>(errno);
}
if (res != abs_pos) {
printf("Failed to see to target (target %zd, got %zd)\n",
static_cast<ssize_t>(abs_pos),
static_cast<ssize_t>(res));
return ZX_ERR_IO;
}
return ZX_OK;
}