This repository has been archived by the owner on Mar 28, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 291
/
AudioStreamInput.cxx
132 lines (107 loc) · 3.74 KB
/
AudioStreamInput.cxx
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
//
// echoprint-codegen
// Copyright 2011 The Echo Nest Corporation. All rights reserved.
//
#include <stddef.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <vector>
#ifndef _WIN32
#include <unistd.h>
#define POPEN_MODE "r"
#else
#include "win_unistd.h"
#include <winsock.h>
#define POPEN_MODE "rb"
#endif
#include <string.h>
#include "AudioStreamInput.h"
#include "Common.h"
#include "Params.h"
using std::string;
namespace FFMPEG {
// Do we think FFmpeg will read this as an audio file?
bool IsAudioFile(const char* pFileName) {
static const char* supportedExtensions[] = {".mp3", ".m4a", ".mp4", ".aif", ".aiff", ".flac", ".au", ".wav", ".aac", ".flv"};
// Not an exhaustive list. ogg and rm could be added if tested.
for (uint i = 0; i < NELEM(supportedExtensions); i++) {
if (File::ends_with(pFileName, supportedExtensions[i]))
return true;
}
return false;
}
}
bool AudioStreamInput::IsSupported(const char *path) {
return true; // Take a crack at anything, by default. The worst thing that will happen is that we fail.
}
AudioStreamInput::AudioStreamInput() : _pSamples(NULL), _NumberSamples(0), _Offset_s(0), _Seconds(0) {}
AudioStreamInput::~AudioStreamInput() {
if (_pSamples != NULL)
delete [] _pSamples, _pSamples = NULL;
}
bool AudioStreamInput::ProcessFile(const char* filename, int offset_s/*=0*/, int seconds/*=0*/) {
if (!File::Exists(filename) || !IsSupported(filename))
return false;
_Offset_s = offset_s;
_Seconds = seconds;
std::string message = GetCommandLine(filename);
FILE* fp = popen(message.c_str(), POPEN_MODE);
bool ok = (fp != NULL);
if (ok)
{
bool did_work = ProcessFilePointer(fp);
bool succeeded = !pclose(fp);
ok = did_work && succeeded;
}
else
fprintf(stderr, "AudioStreamInput::ProcessFile can't open %s\n", filename);
return ok;
}
// reads raw signed 16-bit shorts from a file
bool AudioStreamInput::ProcessRawFile(const char* rawFilename) {
FILE* fp = fopen(rawFilename, "r"); // TODO: Windows
bool ok = (fp != NULL);
if (ok)
{
ok = ProcessFilePointer(fp);
fclose(fp);
}
return ok;
}
// reads raw signed 16-bit shorts from stdin, for example:
// ffmpeg -i fille.mp3 -f s16le -ac 1 -ar 11025 - | TestAudioSTreamInput
bool AudioStreamInput::ProcessStandardInput(void) {
// TODO - Windows will explodey at not setting O_BINARY on stdin.
return ProcessFilePointer(stdin);
}
bool AudioStreamInput::ProcessFilePointer(FILE* pFile) {
std::vector<short*> vChunks;
uint nSamplesPerChunk = (uint) Params::AudioStreamInput::SamplingRate * Params::AudioStreamInput::SecondsPerChunk;
uint samplesRead = 0;
do {
short* pChunk = new short[nSamplesPerChunk];
samplesRead = fread(pChunk, sizeof (short), nSamplesPerChunk, pFile);
_NumberSamples += samplesRead;
vChunks.push_back(pChunk);
} while (samplesRead > 0);
// Convert from shorts to 16-bit floats and copy into sample buffer.
uint sampleCounter = 0;
_pSamples = new float[_NumberSamples];
uint samplesLeft = _NumberSamples;
for (uint i = 0; i < vChunks.size(); i++)
{
short* pChunk = vChunks[i];
uint numSamples = samplesLeft < nSamplesPerChunk ? samplesLeft : nSamplesPerChunk;
for (uint j = 0; j < numSamples; j++)
_pSamples[sampleCounter++] = (float) pChunk[j] / 32768.0f;
samplesLeft -= numSamples;
delete [] pChunk, vChunks[i] = NULL;
}
assert(samplesLeft == 0);
int error = ferror(pFile);
bool success = error == 0;
if (!success)
perror("ProcessFilePointer error");
return success;
}