Hand-apply d849d411cff28ef5453085791d0b4d7cd73bd070 from master; replace all assert...
[dcpomatic.git] / src / lib / audio_analysis.cc
1 /*
2     Copyright (C) 2012 Carl Hetherington <cth@carlh.net>
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #include "audio_analysis.h"
21 #include "dcpomatic_assert.h"
22 #include "cross.h"
23 #include <boost/filesystem.hpp>
24 #include <stdint.h>
25 #include <cmath>
26 #include <cassert>
27 #include <cstdio>
28 #include <iostream>
29
30 using std::ostream;
31 using std::istream;
32 using std::string;
33 using std::vector;
34 using std::cout;
35 using std::max;
36 using std::list;
37
38 AudioPoint::AudioPoint ()
39 {
40         for (int i = 0; i < COUNT; ++i) {
41                 _data[i] = 0;
42         }
43 }
44
45 AudioPoint::AudioPoint (FILE* f)
46 {
47         for (int i = 0; i < COUNT; ++i) {
48                 int n = fscanf (f, "%f", &_data[i]);
49                 if (n != 1) {
50                         _data[i] = 0;
51                 }
52         }
53 }
54
55 AudioPoint::AudioPoint (AudioPoint const & other)
56 {
57         for (int i = 0; i < COUNT; ++i) {
58                 _data[i] = other._data[i];
59         }
60 }
61
62 AudioPoint &
63 AudioPoint::operator= (AudioPoint const & other)
64 {
65         if (this == &other) {
66                 return *this;
67         }
68         
69         for (int i = 0; i < COUNT; ++i) {
70                 _data[i] = other._data[i];
71         }
72
73         return *this;
74 }
75
76 void
77 AudioPoint::write (FILE* f) const
78 {
79         for (int i = 0; i < COUNT; ++i) {
80                 fprintf (f, "%f\n", _data[i]);
81         }
82 }
83         
84
85 AudioAnalysis::AudioAnalysis (int channels)
86 {
87         _data.resize (channels);
88 }
89
90 AudioAnalysis::AudioAnalysis (boost::filesystem::path filename)
91 {
92         FILE* f = fopen_boost (filename, "r");
93
94         int channels = 0;
95         fscanf (f, "%d", &channels);
96         _data.resize (channels);
97
98         for (int i = 0; i < channels; ++i) {
99                 int points;
100                 fscanf (f, "%d", &points);
101                 if (feof (f)) {
102                         fclose (f);
103                         return;
104                 }
105                 
106                 for (int j = 0; j < points; ++j) {
107                         _data[i].push_back (AudioPoint (f));
108                         if (feof (f)) {
109                                 fclose (f);
110                                 return;
111                         }
112                 }
113         }
114
115         fclose (f);
116 }
117
118 void
119 AudioAnalysis::add_point (int c, AudioPoint const & p)
120 {
121         DCPOMATIC_ASSERT (c < channels ());
122         _data[c].push_back (p);
123 }
124
125 AudioPoint
126 AudioAnalysis::get_point (int c, int p) const
127 {
128         DCPOMATIC_ASSERT (p < points (c));
129         return _data[c][p];
130 }
131
132 int
133 AudioAnalysis::channels () const
134 {
135         return _data.size ();
136 }
137
138 int
139 AudioAnalysis::points (int c) const
140 {
141         DCPOMATIC_ASSERT (c < channels ());
142         return _data[c].size ();
143 }
144
145 void
146 AudioAnalysis::write (boost::filesystem::path filename)
147 {
148         boost::filesystem::path tmp = filename;
149         tmp.replace_extension (".tmp");
150
151         FILE* f = fopen_boost (tmp, "w");
152
153         fprintf (f, "%ld\n", _data.size ());
154         for (vector<vector<AudioPoint> >::iterator i = _data.begin(); i != _data.end(); ++i) {
155                 fprintf (f, "%ld\n", i->size ());
156                 for (vector<AudioPoint>::iterator j = i->begin(); j != i->end(); ++j) {
157                         j->write (f);
158                 }
159         }
160
161         fclose (f);
162         boost::filesystem::rename (tmp, filename);
163 }