1/* Sound.cc - an object that holds the sound structure
2 * Copyright (C) 2006-2007, Pino Toscano <pino@kde.org>
3 * Copyright (C) 2009, 2017-2020, Albert Astals Cid <aacid@kde.org>
4 * Copyright (C) 2020, Oliver Sander <oliver.sander@tu-dresden.de>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21#include "Object.h"
22#include "Sound.h"
23#include "Stream.h"
24#include "FileSpec.h"
25
26std::unique_ptr<Sound> Sound::parseSound(Object *obj)
27{
28 // let's try to see if this Object is a Sound, according to the PDF specs
29 // (section 9.2)
30 Stream *str = nullptr;
31 // the Object must be a Stream
32 if (obj->isStream()) {
33 str = obj->getStream();
34 } else {
35 return nullptr;
36 }
37 // the Stream must have a Dict
38 Dict *dict = str->getDict();
39 if (dict == nullptr) {
40 return nullptr;
41 }
42 // the Dict must have the 'R' key of type num
43 Object tmp = dict->lookup(key: "R");
44 if (tmp.isNum()) {
45 return std::unique_ptr<Sound>(new Sound(obj));
46 } else {
47 return nullptr;
48 }
49}
50
51Sound::Sound(const Object *obj, bool readAttrs)
52{
53 streamObj = obj->copy();
54
55 samplingRate = 0.0;
56 channels = 1;
57 bitsPerSample = 8;
58 encoding = soundRaw;
59
60 if (readAttrs) {
61 Dict *dict = streamObj.getStream()->getDict();
62 Object tmp = dict->lookup(key: "F");
63 if (!tmp.isNull()) {
64 // valid 'F' key -> external file
65 kind = soundExternal;
66 Object obj1 = getFileSpecNameForPlatform(fileSpec: &tmp);
67 if (obj1.isString()) {
68 fileName = obj1.getString()->toStr();
69 }
70 } else {
71 // no file specification, then the sound data have to be
72 // extracted from the stream
73 kind = soundEmbedded;
74 }
75 // sampling rate
76 samplingRate = dict->lookup(key: "R").getNumWithDefaultValue(defaultValue: 0);
77 // sound channels
78 tmp = dict->lookup(key: "C");
79 if (tmp.isInt()) {
80 channels = tmp.getInt();
81 }
82 // bits per sample
83 tmp = dict->lookup(key: "B");
84 if (tmp.isInt()) {
85 bitsPerSample = tmp.getInt();
86 }
87 // encoding format
88 tmp = dict->lookup(key: "E");
89 if (tmp.isName()) {
90 const char *enc = tmp.getName();
91 if (strcmp(s1: "Raw", s2: enc) == 0) {
92 encoding = soundRaw;
93 } else if (strcmp(s1: "Signed", s2: enc) == 0) {
94 encoding = soundSigned;
95 } else if (strcmp(s1: "muLaw", s2: enc) == 0) {
96 encoding = soundMuLaw;
97 } else if (strcmp(s1: "ALaw", s2: enc) == 0) {
98 encoding = soundALaw;
99 }
100 }
101 }
102}
103
104Sound::~Sound() { }
105
106Stream *Sound::getStream()
107{
108 return streamObj.getStream();
109}
110
111Sound *Sound::copy() const
112{
113 Sound *newsound = new Sound(&streamObj, false);
114
115 newsound->kind = kind;
116 newsound->fileName = fileName;
117 newsound->samplingRate = samplingRate;
118 newsound->channels = channels;
119 newsound->bitsPerSample = bitsPerSample;
120 newsound->encoding = encoding;
121
122 return newsound;
123}
124

source code of poppler/poppler/Sound.cc