File: qwavheader.cc

package info (click to toggle)
quelcom 0.4.0-16
  • links: PTS
  • area: main
  • in suites: bookworm
  • size: 1,544 kB
  • sloc: cpp: 4,148; makefile: 158; sh: 15
file content (188 lines) | stat: -rw-r--r-- 4,702 bytes parent folder | download | duplicates (3)
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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
/*! \file
 * implementation functions for class qwavheader
 */

# include <string.h>         // memmove

# include "qwavheader.hh"
# include "qexception.hh"
# include "qmisc.hh"
# include "endian.hh"

#ifdef NLS
  # include <locale.h>
  # include <libintl.h>
  # define _(s) gettext (s)
#else
  # define _(s) (s)
#endif


const u_int32_t qwavheader::HEADERSIZE = sizeof(struct wavheader);


qwavheader::qwavheader (caddr_t p, u_int32_t wavlength) {

  header = new wavheader(p);
  mappedheader = (struct wavheader *)p;

  valid();

  if (wavlength)
    validLength(wavlength);
}

qwavheader::~qwavheader()
{
  delete header;
}

void qwavheader::remap(caddr_t p) {
  mappedheader = (struct wavheader *)p;
  header->headerCopy(p);
}


u_int32_t qwavheader::setSamples(u_int32_t n) {

 // protegir-la d'abusos... 
  header->datalength = n*header->bytespersample;
  header->rifflength = header->datalength+36;

  mappedheader->datalength = htolel(header->datalength);
  mappedheader->rifflength = htolel(header->rifflength);

#ifdef QVERBOSE
  cerr << "sample number set to " << n << endl;
#endif

  return getSamples();
}


u_int32_t qwavheader::addSamples(int increment) {
  
 // protegir-la d'abusos...
  setSamples(getSamples()+increment);

  return getSamples();
}


u_int32_t qwavheader::getSamples() {
  return header->datalength / header->bytespersample;
}


bool qwavheader::compatible (const qwavheader &other) {

  return (header->channels == other.header->channels)  &&
       (header->samplerate == other.header->samplerate);
}


bool qwavheader::valid () {
    
  if (!strcmpn(header->riff,"RIFF",4) ||
      !strcmpn(header->wave,"WAVE",4) ||
      !strcmpn(header->fmt_,"fmt ",4) ||
      !strcmpn(header->data,"data",4) ||
      (header->fmtlength!=16        ) ||
      (header->format!=1            )) {

    throw qexception(__PRETTY_FUNCTION__,_("header format error"));
  }

  if ( (header->channels!=2 && header->channels!=1) ||
       (header->samplerate>48000 || header->samplerate<8000) ||
       (header->bytespersample!=1 &&
        header->bytespersample!=2 &&
        header->bytespersample!=4) )

    throw qexception(__PRETTY_FUNCTION__,_("header value error"));

 // caldria comprovar que bitspersample=bytespersample*channels*8
 // caldria comprovar que bytespersec=bytespersample*samplerate
 
  return true;
}


bool qwavheader::validLength (u_int32_t length) {

  if ((header->datalength != length-44) || (header->rifflength != length-8))
    throw qexception(__PRETTY_FUNCTION__,_("length mismatch"));

  return true;
}


u_int32_t qwavheader::getMsDuration() { 
  return 1000ULL*header->datalength/(header->bytespersample*header->samplerate); 
} 

u_int32_t qwavheader::getSampleRate() { return header->samplerate; } 
u_int32_t qwavheader::getChannels() { return header->channels; } 


u_int32_t qwavheader::getOffset (qvf &vf) { 

  return getSample(vf)*getBytesPerSample()+HEADERSIZE;
}


u_int32_t qwavheader::getOffset (u_int32_t sample) { 
 // assegurar que sample in (1..getSamples())
  return HEADERSIZE+(sample-1)*header->bytespersample; 
}


u_int32_t qwavheader::getSample (qvf &vf) { 

  u_int32_t sample;

  switch (vf.getFormat()) {

    case qvf::BYTES: sample = vf.getValue()/getBytesPerSample(); break;
    case qvf::KBYTES: sample = (vf.getValue()*1024)/getBytesPerSample(); break;
    case qvf::MBYTES: sample = (vf.getValue()*1024*1024)/getBytesPerSample(); break;

    case qvf::MILLISECONDS: sample = (1ULL*vf.getValue()*getSampleRate())/1000; break;
    case qvf::SECONDS: sample = vf.getValue()*getSampleRate(); break;
    case qvf::MINUTES: sample = 60*vf.getValue()*getSampleRate(); break;

    case qvf::SPECIFIC: sample = vf.getValue(); break;

    default:
      throw qexception(__PRETTY_FUNCTION__,
              string(_("format not recognized: "))+char2string(vf.getFormat()));
  }

  if (sample<1 || sample>getSamples())
    throw qexception(__PRETTY_FUNCTION__,string(_("sample out of range: "))+uint2string(sample));
  // i si posssim el qvf, millor

  return sample;
}

u_int32_t qwavheader::getBitsPerSample() { return header->bitspersample; }
u_int32_t qwavheader::getBytesPerSample() { return header->bytespersample; }
bool qwavheader::getStereo() { return header->channels==2; }

void qwavheader::wavheader::headerCopy(caddr_t p)
{
  memmove(this, p, HEADERSIZE);

#if __BYTE_ORDER != __LITTLE_ENDIAN
  rifflength = letohl(rifflength);
  fmtlength = letohl(fmtlength);
  format = letohs(format);
  channels = letohs(channels);
  samplerate = letohl(samplerate);
  bytespersec = letohl(bytespersec);
  bytespersample = letohs(bytespersample);
  bitspersample = letohs(bitspersample);
  datalength = letohl(datalength);
#endif

}