1 // Copyright 2017 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <errno.h>
6 #include <fcntl.h>
7 #include <zircon/assert.h>
8 #include <fbl/auto_call.h>
9 #include <fbl/algorithm.h>
10 #include <lib/fdio/io.h>
11 #include <stdio.h>
12
13 #include "wav-source.h"
14
15 constexpr uint32_t WAVCommon::RIFF_FOUR_CC;
16 constexpr uint32_t WAVCommon::WAVE_FOUR_CC;
17 constexpr uint32_t WAVCommon::FMT_FOUR_CC;
18 constexpr uint32_t WAVCommon::DATA_FOUR_CC;
19
20 constexpr uint16_t WAVCommon::FORMAT_UNKNOWN;
21 constexpr uint16_t WAVCommon::FORMAT_LPCM;
22 constexpr uint16_t WAVCommon::FORMAT_MSFT_ADPCM;
23 constexpr uint16_t WAVCommon::FORMAT_IEEE_FLOAT;
24 constexpr uint16_t WAVCommon::FORMAT_MSFT_ALAW;
25 constexpr uint16_t WAVCommon::FORMAT_MSFT_MULAW;
26
Initialize(const char * filename,InitMode mode)27 zx_status_t WAVCommon::Initialize(const char* filename, InitMode mode) {
28 if (fd_ >= 0) {
29 printf("Failed to initialize WAVCommon for \"%s\", already initialized\n", filename);
30 return ZX_ERR_BAD_STATE;
31 }
32
33 int flags = (mode == InitMode::SOURCE)
34 ? O_RDONLY
35 : O_RDWR | O_CREAT;
36 fd_ = ::open(filename, flags);
37 if (fd_ < 0) {
38 printf("Failed to open \"%s\" (res %d)\n", filename, fd_);
39 return static_cast<zx_status_t>(fd_);
40 }
41
42 return ZX_OK;
43 }
44
Close()45 void WAVCommon::Close() {
46 if (fd_ >= 0) {
47 ::close(fd_);
48 fd_ = -1;
49 }
50 }
51
Read(void * buf,size_t len)52 zx_status_t WAVCommon::Read(void* buf, size_t len) {
53 if (fd_ < 0) return ZX_ERR_BAD_STATE;
54
55 ssize_t res = ::read(fd_, buf, len);
56 if (res < 0) {
57 printf("Read error (errno %d)\n", errno);
58 return static_cast<zx_status_t>(errno);
59 }
60
61 if (static_cast<size_t>(res) != len) {
62 printf("Short read error (%zd < %zu)\n", res, len);
63 return ZX_ERR_IO;
64 }
65
66 return ZX_OK;
67 }
68
Write(const void * buf,size_t len)69 zx_status_t WAVCommon::Write(const void* buf, size_t len) {
70 if (fd_ < 0) return ZX_ERR_BAD_STATE;
71
72 ssize_t res = ::write(fd_, buf, len);
73 if (res < 0) {
74 printf("Write error (errno %d)\n", errno);
75 return static_cast<zx_status_t>(errno);
76 }
77
78 if (static_cast<size_t>(res) != len) {
79 printf("Short write error (%zd < %zu)\n", res, len);
80 return ZX_ERR_IO;
81 }
82
83 return ZX_OK;
84 }
85
Seek(off_t abs_pos)86 zx_status_t WAVCommon::Seek(off_t abs_pos) {
87 if (fd_ < 0) return ZX_ERR_BAD_STATE;
88 if (abs_pos < 0) return ZX_ERR_INVALID_ARGS;
89
90 off_t res = ::lseek(fd_, abs_pos, SEEK_SET);
91 if (res < 0) {
92 printf("Seek error (errno %d)\n", errno);
93 return static_cast<zx_status_t>(errno);
94 }
95
96 if (res != abs_pos) {
97 printf("Failed to see to target (target %zd, got %zd)\n",
98 static_cast<ssize_t>(abs_pos),
99 static_cast<ssize_t>(res));
100 return ZX_ERR_IO;
101 }
102
103 return ZX_OK;
104 }
105