File size: 4,346 Bytes
28889d1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/*
* Copyright (c) 2019, NVIDIA Corporation.  All rights reserved.
*
* NVIDIA Corporation and its licensors retain all intellectual property
* and proprietary rights in and to this software, related documentation
* and any modifications thereto.  Any use, reproduction, disclosure or
* distribution of this software and related documentation without an express
* license agreement from NVIDIA Corporation is strictly prohibited.
*/

#pragma once

#include <string>

#ifndef WAVE_FORMAT_PCM
#define WAVE_FORMAT_PCM        0x0001
#endif
#define WAVE_FORMAT_IEEE_FLOAT 0x0003
#define WAVE_FORMAT_ALAW       0x0006
#define WAVE_FORMAT_MULAW      0x0007
#define WAVE_FORMAT_EXTENSIBLE 0xFFFE

#define WAVE_WAVE   0x45564157  // 'EVAW' (little endian WAVE)
#define WAVE_RIFF   0x46464952  // 'FFIR' (little endian RIFF)
#define WAVE_FORMAT 0x20746D66  // ' tmf' (little endian fmt )
#define WAVE_DATA   0x61746164  // 'atad' (little endian data)

#define DEBUG 1

#if DEBUG
#define PRINTCONTROL(x) x;
#define WAVE_ZERO_ON_ALLOCATE 1
#else
#define PRINTCONTROL(x)
#define WAVE_ZERO_ON_ALLOCATE 0
#endif

#define MAX_CHANNELS 64

typedef struct {
  int ckId;
  int cksize;
  int waveId;
  int waveChunks;
} WaveHeader;

typedef struct {
  uint16_t   formatTag;         /* format type */
  uint16_t   nChannels;         /* number of channels (i.e. mono, stereo...) */
  unsigned int     nSamplesPerSec;    /* sample rate */
  unsigned int     nAvgBytesPerSec;   /* for buffer estimation */
  uint16_t   nBlockAlign;       /* block size of data */
} waveFormat_basic_nopcm;

typedef struct {
  uint16_t   formatTag;         /* format type */
  uint16_t   nChannels;         /* number of channels (i.e. mono, stereo...) */
  unsigned int     nSamplesPerSec;    /* sample rate */
  unsigned int     nAvgBytesPerSec;   /* for buffer estimation */
  uint16_t   nBlockAlign;       /* block size of data */
  uint16_t   wBitsPerSample;    /* Number of bits per sample of mono data */
} waveFormat_basic;

typedef struct {
  uint16_t   wFormatTag;         /* format type */
  uint16_t   nChannels;         /* number of channels (i.e. mono, stereo...) */
  unsigned int     nSamplesPerSec;    /* sample rate */
  unsigned int     nAvgBytesPerSec;   /* for buffer estimation */
  uint16_t   nBlockAlign;       /* block size of data */
  uint16_t   wBitsPerSample;    /* Number of bits per sample of mono data */
  uint16_t   cbSize;      /* the count in bytes of the size of */
  /* extra information (after cbSize) */
} waveFormat_ext;

class Wave {
 public:
  Wave();
  explicit Wave(std::string filename);
  Wave(const Wave & argB);
  ~Wave();

  /* Tools for creating waves in software */
  Wave(unsigned int nSamples, unsigned int nChannels, unsigned int sampleRate, unsigned int bitDepth);

  // Special Constructor used for construction by extractChannel
  Wave(unsigned int nSamples, unsigned int sampleRate, unsigned int bitDepth, float * singleChannel);

  /* Tools for allowing waves to interact */
  Wave & operator -=(const Wave & argB);
  Wave & operator *=(float scale);
  void operator >> (int shiftSamples);
  void operator >> (float shiftSeconds);
  void operator <<(int shiftSamples);
  void operator <<(float shiftSeconds);

  float& operator[](int sampleIndex);
  float* getDataPtr(int channelIndex, int sampleIndex);

  Wave extractChannel(int channelIndex);
  void setChannel(int channelIndex, Wave* argB);

  unsigned int getNumSamples();
  unsigned int getNumChannels();
  unsigned int getBitDepth();
  unsigned int getSampleRate();

  void         writeFile(std::string filename);
  int          maxInt(int channelId);
  int          minInt(int channelId);
  float        maxFloat(int channelId);
  float        minFloat(int channelId);
  void         append(int numChannels, int numAppendedSamples, float ** buffers);

  void         normalize();

 private:
  unsigned int m_numChannels;
  unsigned int m_sampleRate;
  unsigned int m_bitDepth;
  unsigned int m_numSamples;
  unsigned int m_bufferAllocation;

  int  ** m_intData;
  float ** m_floatData;

  bool    m_PCMIntValid;
  bool    m_PCMFloatValid;

  bool allocateInt();
  bool allocateFloat();
  void reallocate();

  void freeInt();
  void freeFloat();

  void fillFloatFromInt();
  void fillIntFromFloat();
  void validFloat();

  void readFromFile(std::string filename);
};