File: SampleFormat.cpp

package info (click to toggle)
audacity 3.7.7%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 134,800 kB
  • sloc: cpp: 366,277; ansic: 198,323; lisp: 7,761; sh: 3,414; python: 1,501; xml: 1,385; perl: 854; makefile: 125
file content (118 lines) | stat: -rw-r--r-- 3,742 bytes parent folder | download | duplicates (2)
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
/**********************************************************************

  Audacity: A Digital Audio Editor

  SampleFormat.h

  Dominic Mazzoni

*******************************************************************//*!

\file SampleFormat.cpp
\brief Functions that work with Dither and initialise it.


  This file handles converting between all of the different
  sample formats that Audacity supports, such as 16-bit,
  24-bit (packed into a 32-bit int), and 32-bit float.

  Floating-point samples use the range -1.0...1.0, inclusive.
  Integer formats use the full signed range of their data type,
  for example 16-bit samples use the range -32768...32767.
  This means that reading in a wav file and writing it out again
  ('round tripping'), via floats, is lossless; -32768 equates to -1.0f
  and 32767 equates to +1.0f - (a little bit).
  It also means (unfortunately) that writing out +1.0f leads to
  clipping by 1 LSB.  This creates some distortion, but I (MJS) have
  not been able to measure it, it's so small.  Zero is preserved.

  http://limpet.net/audacity/bugzilla/show_bug.cgi?id=200
  leads to some of the discussions that were held about this.

   Note: These things are now handled by the Dither class, which
         also replaces the CopySamples() method (msmeyer)

*//*******************************************************************/

#include "SampleFormat.h"
#include "Dither.h" // CYCLE

#include <math.h>
#include <stdlib.h>
#include <string.h>

#include "Prefs.h"
#include "Internat.h"

DitherType gLowQualityDither = DitherType::none;
DitherType gHighQualityDither = DitherType::shaped;
static Dither gDitherAlgorithm;

void InitDitherers()
{
   // Read dither preferences
   gLowQualityDither = Dither::FastDitherChoice();
   gHighQualityDither = Dither::BestDitherChoice();
}

TranslatableString GetSampleFormatStr(sampleFormat format)
{
   switch(format) {
   case int16Sample:
      /* i18n-hint: Audio data bit depth (precision): 16-bit integers */
      return XO("16-bit PCM");
   case int24Sample:
      /* i18n-hint: Audio data bit depth (precision): 24-bit integers */
      return XO("24-bit PCM");
   case floatSample:
      /* i18n-hint: Audio data bit depth (precision): 32-bit floating point */
      return XO("32-bit float");
   }
   return XO("Unknown format"); // compiler food
}

// TODO: Risky?  Assumes 0.0f is represented by 0x00000000;
void ClearSamples(samplePtr dst, sampleFormat format,
                  size_t start, size_t len)
{
   auto size = SAMPLE_SIZE(format);
   memset(dst + start*size, 0, len*size);
}

void ReverseSamples(samplePtr dst, sampleFormat format,
                  int start, int len)
{
   auto size = SAMPLE_SIZE(format);
   samplePtr first = dst + start * size;
   samplePtr last = dst + (start + len - 1) * size;
   enum : size_t { fixedSize = SAMPLE_SIZE(floatSample) };
   wxASSERT(static_cast<size_t>(size) <= fixedSize);
   char temp[fixedSize];
   while (first < last) {
      memcpy(temp, first, size);
      memcpy(first, last, size);
      memcpy(last, temp, size);
      first += size;
      last -= size;
   }
}

void  SamplesToFloats(constSamplePtr src, sampleFormat srcFormat,
   float *dst, size_t len, size_t srcStride, size_t dstStride)
{
   CopySamples( src, srcFormat,
      reinterpret_cast<samplePtr>(dst), floatSample, len,
      DitherType::none,
      srcStride, dstStride);
}

void CopySamples(constSamplePtr src, sampleFormat srcFormat,
   samplePtr dst, sampleFormat dstFormat, size_t len,
   DitherType ditherType, /* = gHighQualityDither */
   unsigned int srcStride /* = 1 */,
   unsigned int dstStride /* = 1 */)
{
   gDitherAlgorithm.Apply(
      ditherType,
      src, srcFormat, dst, dstFormat, len, srcStride, dstStride);
}