├── Debug
├── libhackrf.dll
├── libhackrf.exp
├── libhackrf.ilk
├── libhackrf.lib
├── libhackrf.pdb
├── pthreadGC2.dll
├── pthreadGCE2.dll
├── pthreadVC2.dll
├── pthreadVCE2.dll
└── pthreadVSE2.dll
├── HackRF_Transmitter.v12.suo
├── README.md
├── HackRF_Transmitter
├── HackRF_Transmitter.vcxproj.user
├── IHackRFData.h
├── WavSource.cpp
├── HackRFDevice.h
├── WavSource.h
├── FMModulator.h
├── HackRFDevice.cpp
├── main.cpp
├── HackRF_Transmitter.vcxproj.filters
├── input.h
├── write_wav.h
├── FMModulator.cpp
├── HackRF_Transmitter.vcxproj
├── write_wav.cpp
├── hackrf.h
└── input.cpp
└── HackRF_Transmitter.sln
/Debug/libhackrf.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gsj0791/HackRF_FM_Transmitter/HEAD/Debug/libhackrf.dll
--------------------------------------------------------------------------------
/Debug/libhackrf.exp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gsj0791/HackRF_FM_Transmitter/HEAD/Debug/libhackrf.exp
--------------------------------------------------------------------------------
/Debug/libhackrf.ilk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gsj0791/HackRF_FM_Transmitter/HEAD/Debug/libhackrf.ilk
--------------------------------------------------------------------------------
/Debug/libhackrf.lib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gsj0791/HackRF_FM_Transmitter/HEAD/Debug/libhackrf.lib
--------------------------------------------------------------------------------
/Debug/libhackrf.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gsj0791/HackRF_FM_Transmitter/HEAD/Debug/libhackrf.pdb
--------------------------------------------------------------------------------
/Debug/pthreadGC2.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gsj0791/HackRF_FM_Transmitter/HEAD/Debug/pthreadGC2.dll
--------------------------------------------------------------------------------
/Debug/pthreadGCE2.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gsj0791/HackRF_FM_Transmitter/HEAD/Debug/pthreadGCE2.dll
--------------------------------------------------------------------------------
/Debug/pthreadVC2.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gsj0791/HackRF_FM_Transmitter/HEAD/Debug/pthreadVC2.dll
--------------------------------------------------------------------------------
/Debug/pthreadVCE2.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gsj0791/HackRF_FM_Transmitter/HEAD/Debug/pthreadVCE2.dll
--------------------------------------------------------------------------------
/Debug/pthreadVSE2.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gsj0791/HackRF_FM_Transmitter/HEAD/Debug/pthreadVSE2.dll
--------------------------------------------------------------------------------
/HackRF_Transmitter.v12.suo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gsj0791/HackRF_FM_Transmitter/HEAD/HackRF_Transmitter.v12.suo
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # HackRF_FM_Transmitter
2 | HackRF FM Transmitter On Windows
3 | This Code base On https://github.com/jocover/foo_hackrf
4 |
--------------------------------------------------------------------------------
/HackRF_Transmitter/HackRF_Transmitter.vcxproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/HackRF_Transmitter/IHackRFData.h:
--------------------------------------------------------------------------------
1 | #ifndef _IHACKRFDATA_H
2 | #define _IHACKRFDATA_H
3 |
4 | #include
5 |
6 | class IHackRFData
7 | {
8 | public:
9 | IHackRFData() {};
10 | ~IHackRFData() {};
11 |
12 | virtual int onData(int8_t* buffer, uint32_t length) = 0;
13 | };
14 |
15 | #endif // !_IHACKRFDATA_H
16 |
--------------------------------------------------------------------------------
/HackRF_Transmitter/WavSource.cpp:
--------------------------------------------------------------------------------
1 | #include "WavSource.h"
2 |
3 | #define DEBUG 1
4 |
5 | WavSource::WavSource(const char *filename, int inputSamples)
6 | :_inputSamples(inputSamples)
7 | {
8 | pcmHeader = wav_open_read(filename, 0);
9 | audioDataPos = ftell(pcmHeader->f);
10 | _buf = (float *)malloc(inputSamples*sizeof(float)* pcmHeader->channels);
11 | }
12 |
13 |
14 | WavSource::~WavSource()
15 | {
16 | free(_buf);
17 | wav_close(pcmHeader);
18 | }
19 |
20 | int WavSource::readData(){
21 | return wav_read_float32(pcmHeader, _buf, _inputSamples * pcmHeader->channels, NULL);
22 | }
23 |
24 | void WavSource::reset(){
25 | fseek(pcmHeader->f, audioDataPos, SEEK_SET);
26 | }
27 |
28 |
29 |
--------------------------------------------------------------------------------
/HackRF_Transmitter/HackRFDevice.h:
--------------------------------------------------------------------------------
1 | #ifndef _HACKRFDEIVCE_H
2 | #define _HACKRFDEIVCE_H
3 | #include "IHackRFData.h"
4 | #include "hackrf.h"
5 | #include
6 | #include
7 |
8 | class HackRFDevice
9 | {
10 | private:
11 | hackrf_device *_dev;
12 | IHackRFData *mHandler;
13 | bool running;
14 | uint32_t hackrf_sample = 2000000;
15 |
16 | public:
17 | HackRFDevice();
18 | ~HackRFDevice();
19 |
20 | int HackRFCallback(int8_t* buffer, uint32_t length);
21 |
22 | bool Open(IHackRFData *handler);
23 | void SetFrequency(uint64_t freg);
24 | void SetGain(float gain);
25 | void SetAMP(bool enableamp);
26 | void SetSampleRate(uint32_t sample_rate);
27 | bool StartTx();
28 | void Close();
29 | };
30 |
31 | #endif // !
32 |
--------------------------------------------------------------------------------
/HackRF_Transmitter/WavSource.h:
--------------------------------------------------------------------------------
1 | #ifndef _WAVSOURCE_H
2 | #define _WAVSOURCE_H
3 |
4 | #include "input.h"
5 |
6 | class WavSource
7 | {
8 | private:
9 | pcmfile_t *pcmHeader;
10 | float *_buf;
11 | int _inputSamples;
12 | int audioDataPos = 0;
13 |
14 | public:
15 | WavSource(const char *filename, int inputSamples);
16 | ~WavSource();
17 |
18 | int readData();
19 | int getChannels(){ return pcmHeader->channels; };
20 | int getSampleRate(){ return pcmHeader->samplerate; }
21 | int getSampleByte(){ return pcmHeader->samplebytes; }
22 | int getSamples(){ return pcmHeader->samples; }
23 | int getSampleCount(){ return _inputSamples; }
24 | float *getData() { return _buf; };
25 | void reset();
26 | };
27 |
28 | #endif // !_WAVSOURCE_H
29 |
30 |
--------------------------------------------------------------------------------
/HackRF_Transmitter/FMModulator.h:
--------------------------------------------------------------------------------
1 | #ifndef _FMMODULATOR_H
2 | #define _FMMODULATOR_H
3 |
4 | #include
5 | #include "IHackRFData.h"
6 | #include "WavSource.h"
7 |
8 |
9 | #define BUF_LEN 262144 //hackrf tx buf
10 |
11 | class FMModulator:public IHackRFData
12 | {
13 | private:
14 | std::mutex m_mutex;
15 | int count;
16 | int8_t ** _buf_ptr;
17 | bool inited;
18 | int tail;
19 | int head;
20 | float gain;
21 | uint32_t mode;
22 | float * audio_buf;
23 | float * new_audio_buf;
24 | float * IQ_buf;
25 | uint32_t m_sample_rate;
26 | size_t m_sample_count;
27 | uint32_t hackrf_sample;
28 | double fm_phase;
29 | double fm_deviation;
30 | float last_in_samples[4];
31 |
32 | private:
33 | void interpolation(float * in_buf, uint32_t in_samples, float * out_buf, uint32_t out_samples, float last_in_samples[4]);
34 | void modulation(float * input, float * output, uint32_t mode);
35 | void work(float *input_items, uint32_t len);
36 |
37 | public:
38 | FMModulator(float _gain, uint32_t _mode, uint32_t _sample);
39 | ~FMModulator();
40 |
41 | int onData(int8_t* buffer, uint32_t length);
42 | void Start(WavSource *source);
43 | };
44 |
45 | #endif
46 |
47 |
--------------------------------------------------------------------------------
/HackRF_Transmitter/HackRFDevice.cpp:
--------------------------------------------------------------------------------
1 | #include "HackRFDevice.h"
2 |
3 |
4 | int _hackrf_tx_callback(hackrf_transfer *transfer) {
5 | HackRFDevice *obj = (HackRFDevice *)transfer->tx_ctx;
6 | return obj->HackRFCallback((int8_t *)transfer->buffer, transfer->valid_length);
7 | }
8 |
9 | HackRFDevice::HackRFDevice()
10 | :_dev(NULL), running(false)
11 | {
12 | }
13 |
14 |
15 | HackRFDevice::~HackRFDevice()
16 | {
17 | if (_dev) {
18 | this->Close();
19 | }
20 | }
21 |
22 | bool HackRFDevice::Open(IHackRFData *handler){
23 | mHandler = handler;
24 | hackrf_init();
25 |
26 | int ret = hackrf_open(&_dev);
27 | if (ret != HACKRF_SUCCESS) {
28 | printf("Failed to open HackRF device");
29 | hackrf_close(_dev);
30 | return false;
31 | }
32 | return true;
33 | }
34 |
35 | int HackRFDevice::HackRFCallback(int8_t* buffer, uint32_t length)
36 | {
37 | return mHandler->onData(buffer, length);
38 | }
39 |
40 | bool HackRFDevice::StartTx()
41 | {
42 | running = true;
43 | int ret = hackrf_start_tx(_dev, _hackrf_tx_callback, (void *)this);
44 | if (ret != HACKRF_SUCCESS) {
45 | printf("Failed to start TX streaming");
46 | hackrf_close(_dev);
47 | running = false;
48 | }
49 |
50 | return running;
51 | }
52 |
53 | void HackRFDevice::SetFrequency(uint64_t freg)
54 | {
55 | hackrf_set_freq(_dev, freg);
56 | }
57 |
58 | void HackRFDevice::SetGain(float gain)
59 | {
60 | hackrf_set_txvga_gain(_dev, gain);
61 | }
62 |
63 | void HackRFDevice::SetAMP(bool enableamp)
64 | {
65 | hackrf_set_amp_enable(_dev, enableamp);
66 | }
67 |
68 | void HackRFDevice::SetSampleRate(uint32_t sample_rate)
69 | {
70 | hackrf_set_sample_rate(_dev, sample_rate);
71 | hackrf_set_baseband_filter_bandwidth(_dev, 1750000);
72 | }
73 |
74 | void HackRFDevice::Close() {
75 | running = false;
76 | hackrf_stop_tx(_dev);
77 | hackrf_close(_dev);
78 | _dev = NULL;
79 | }
80 |
--------------------------------------------------------------------------------
/HackRF_Transmitter/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include "WavSource.h"
3 | #include "FMModulator.h"
4 | #include "HackRFDevice.h"
5 | #include "write_wav.h"
6 |
7 | #define HACKRF_SAMPLE 2000000
8 | #define SAMPLE_COUNT 2048
9 |
10 | int main(int argc, char *argv[])
11 | {
12 | WavSource *wav = new WavSource("f:\\notouch.wav", SAMPLE_COUNT);
13 |
14 | uint32_t avSamplesPerSecByte = wav->getSampleByte() * wav->getChannels() * wav->getSampleRate();
15 | //176400
16 | int PerTimeStamp = 1000 / (avSamplesPerSecByte / (SAMPLE_COUNT * wav->getChannels()));
17 | int readTotalAudioByte = 0;
18 | int PerSamplesPerSecByte = SAMPLE_COUNT * wav->getSampleByte();
19 | int m_read_buf_size;
20 | int nTimeStamp = 0;
21 | int fTimeStamp = 0;
22 | double audioTimeTick = GetTickCount();
23 |
24 | int sample_rate = wav->getSampleRate()*1.0 / SAMPLE_COUNT*BUF_LEN;
25 |
26 | FMModulator *mod = new FMModulator(90, 0, sample_rate);
27 | HackRFDevice *device = new HackRFDevice();
28 |
29 | if (!device->Open(mod)) {
30 | return 0;
31 | }
32 |
33 | device->SetSampleRate(sample_rate);
34 | device->SetFrequency(2600000000);
35 | device->SetGain(40);
36 | device->SetAMP(0);
37 | device->StartTx();
38 |
39 | //WAV_Writer wavFile;
40 | //Audio_WAV_OpenWriter(&wavFile, "f:\\test11111111111.wav", wav->getSampleRate(), wav->getSampleByte());
41 |
42 | while (1)
43 | {
44 | nTimeStamp = GetTickCount() - audioTimeTick;
45 | fTimeStamp = ((readTotalAudioByte + SAMPLE_COUNT)*2 / PerSamplesPerSecByte) * PerTimeStamp;
46 |
47 | if (nTimeStamp > fTimeStamp){
48 | m_read_buf_size = wav->readData();
49 | //fwrite(wav->getData(), wav->getChannels(), SAMPLE_COUNT * sizeof(float), wavFile.fid);
50 | //wavFile.dataSize += wav->getChannels()* SAMPLE_COUNT * sizeof(float);
51 |
52 | mod->Start(wav);
53 | readTotalAudioByte += m_read_buf_size;
54 | if (!m_read_buf_size){
55 | audioTimeTick = GetTickCount();
56 | readTotalAudioByte = 0;
57 | wav->reset();
58 | }
59 | }
60 | Sleep(5);
61 | }
62 |
63 | //Audio_WAV_CloseWriter(&wavFile);
64 | device->Close();
65 | delete(mod);
66 | return 0;
67 | }
--------------------------------------------------------------------------------
/HackRF_Transmitter/HackRF_Transmitter.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 |
18 |
19 | Header Files
20 |
21 |
22 | Header Files
23 |
24 |
25 | Header Files
26 |
27 |
28 | Header Files
29 |
30 |
31 | Header Files
32 |
33 |
34 | Header Files
35 |
36 |
37 | Header Files
38 |
39 |
40 |
41 |
42 | Source Files
43 |
44 |
45 | Source Files
46 |
47 |
48 | Source Files
49 |
50 |
51 | Source Files
52 |
53 |
54 | Source Files
55 |
56 |
57 | Source Files
58 |
59 |
60 |
--------------------------------------------------------------------------------
/HackRF_Transmitter/input.h:
--------------------------------------------------------------------------------
1 | /*
2 | * FAAC - Freeware Advanced Audio Coder
3 | * Copyright (C) 2002 Krzysztof Nikiel
4 | *
5 | * This library is free software; you can redistribute it and/or
6 | * modify it under the terms of the GNU Lesser General Public
7 | * License as published by the Free Software Foundation; either
8 | * version 2.1 of the License, or (at your option) any later version.
9 | *
10 | * This library is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | * Lesser General Public License for more details.
14 |
15 | * You should have received a copy of the GNU Lesser General Public
16 | * License along with this library; if not, write to the Free Software
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 | *
19 | * $Id: input.h,v 1.7 2008/11/24 22:00:11 menno Exp $
20 | */
21 |
22 | #ifndef _INPUT_H
23 | #define _INPUT_H
24 |
25 | #ifdef HAVE_CONFIG_H
26 | #include "config.h"
27 | #endif
28 |
29 | #include
30 | #include
31 | #ifdef HAVE_SYS_TYPES_H
32 | # include
33 | #endif
34 | #ifndef __MPEG4IP_INCLUDED__
35 | /* Let's avoid some boring conflicting declarations */
36 | #ifdef HAVE_INTTYPES_H
37 | # include
38 | #endif
39 | #ifdef HAVE_STDINT_H
40 | # include
41 | #endif
42 |
43 | #ifndef HAVE_INT32_T
44 | typedef signed int int32_t;
45 | #endif
46 | #ifndef HAVE_INT16_T
47 | typedef signed short int16_t;
48 | #endif
49 | #ifndef HAVE_U_INT32_T
50 | typedef unsigned int u_int32_t;
51 | #endif
52 | #ifndef HAVE_U_INT16_T
53 | typedef unsigned short u_int16_t;
54 | #endif
55 | #endif /* #ifndef __MPEG4IP_INCLUDED__ */
56 |
57 |
58 | typedef struct
59 | {
60 | FILE *f;
61 | int channels;
62 | int samplebytes;
63 | int samplerate;
64 | int samples;
65 | int bigendian;
66 | int isfloat;
67 | } pcmfile_t;
68 |
69 | pcmfile_t *wav_open_read(const char *path, int rawchans);
70 | size_t wav_read_float32(pcmfile_t *sndf, float *buf, size_t num, int *map);
71 | size_t wav_read_int24(pcmfile_t *sndf, int32_t *buf, size_t num, int *map);
72 | size_t wav_read_int24_buf(pcmfile_t *sndf, int32_t *outbuf, size_t num, unsigned char *inputbuf);
73 | int wav_close(pcmfile_t *file);
74 |
75 | #endif /* _INPUT_H */
76 |
--------------------------------------------------------------------------------
/HackRF_Transmitter.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2013
4 | VisualStudioVersion = 12.0.21005.1
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HackRF_Transmitter", "HackRF_Transmitter\HackRF_Transmitter.vcxproj", "{BD76BC64-68F9-470F-A778-593BC958D301}"
7 | EndProject
8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libhackrf", "..\libhackrf\libhackrf\libhackrf.vcxproj", "{27A2D86B-5C35-49ED-AC77-C9F515C9F0E9}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|Mixed Platforms = Debug|Mixed Platforms
13 | Debug|Win32 = Debug|Win32
14 | Debug|x64 = Debug|x64
15 | Debug|x86 = Debug|x86
16 | Release|Mixed Platforms = Release|Mixed Platforms
17 | Release|Win32 = Release|Win32
18 | Release|x64 = Release|x64
19 | Release|x86 = Release|x86
20 | EndGlobalSection
21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
22 | {BD76BC64-68F9-470F-A778-593BC958D301}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
23 | {BD76BC64-68F9-470F-A778-593BC958D301}.Debug|Mixed Platforms.Build.0 = Debug|Win32
24 | {BD76BC64-68F9-470F-A778-593BC958D301}.Debug|Win32.ActiveCfg = Debug|Win32
25 | {BD76BC64-68F9-470F-A778-593BC958D301}.Debug|Win32.Build.0 = Debug|Win32
26 | {BD76BC64-68F9-470F-A778-593BC958D301}.Debug|x64.ActiveCfg = Debug|x64
27 | {BD76BC64-68F9-470F-A778-593BC958D301}.Debug|x64.Build.0 = Debug|x64
28 | {BD76BC64-68F9-470F-A778-593BC958D301}.Debug|x86.ActiveCfg = Debug|Win32
29 | {BD76BC64-68F9-470F-A778-593BC958D301}.Debug|x86.Build.0 = Debug|Win32
30 | {BD76BC64-68F9-470F-A778-593BC958D301}.Release|Mixed Platforms.ActiveCfg = Release|Win32
31 | {BD76BC64-68F9-470F-A778-593BC958D301}.Release|Mixed Platforms.Build.0 = Release|Win32
32 | {BD76BC64-68F9-470F-A778-593BC958D301}.Release|Win32.ActiveCfg = Release|Win32
33 | {BD76BC64-68F9-470F-A778-593BC958D301}.Release|Win32.Build.0 = Release|Win32
34 | {BD76BC64-68F9-470F-A778-593BC958D301}.Release|x64.ActiveCfg = Release|x64
35 | {BD76BC64-68F9-470F-A778-593BC958D301}.Release|x64.Build.0 = Release|x64
36 | {BD76BC64-68F9-470F-A778-593BC958D301}.Release|x86.ActiveCfg = Release|Win32
37 | {BD76BC64-68F9-470F-A778-593BC958D301}.Release|x86.Build.0 = Release|Win32
38 | {27A2D86B-5C35-49ED-AC77-C9F515C9F0E9}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
39 | {27A2D86B-5C35-49ED-AC77-C9F515C9F0E9}.Debug|Mixed Platforms.Build.0 = Debug|Win32
40 | {27A2D86B-5C35-49ED-AC77-C9F515C9F0E9}.Debug|Win32.ActiveCfg = Debug|Win32
41 | {27A2D86B-5C35-49ED-AC77-C9F515C9F0E9}.Debug|Win32.Build.0 = Debug|Win32
42 | {27A2D86B-5C35-49ED-AC77-C9F515C9F0E9}.Debug|x64.ActiveCfg = Debug|x64
43 | {27A2D86B-5C35-49ED-AC77-C9F515C9F0E9}.Debug|x64.Build.0 = Debug|x64
44 | {27A2D86B-5C35-49ED-AC77-C9F515C9F0E9}.Debug|x86.ActiveCfg = Debug|Win32
45 | {27A2D86B-5C35-49ED-AC77-C9F515C9F0E9}.Debug|x86.Build.0 = Debug|Win32
46 | {27A2D86B-5C35-49ED-AC77-C9F515C9F0E9}.Release|Mixed Platforms.ActiveCfg = Release|Win32
47 | {27A2D86B-5C35-49ED-AC77-C9F515C9F0E9}.Release|Mixed Platforms.Build.0 = Release|Win32
48 | {27A2D86B-5C35-49ED-AC77-C9F515C9F0E9}.Release|Win32.ActiveCfg = Release|Win32
49 | {27A2D86B-5C35-49ED-AC77-C9F515C9F0E9}.Release|Win32.Build.0 = Release|Win32
50 | {27A2D86B-5C35-49ED-AC77-C9F515C9F0E9}.Release|x64.ActiveCfg = Release|x64
51 | {27A2D86B-5C35-49ED-AC77-C9F515C9F0E9}.Release|x64.Build.0 = Release|x64
52 | {27A2D86B-5C35-49ED-AC77-C9F515C9F0E9}.Release|x86.ActiveCfg = Release|Win32
53 | {27A2D86B-5C35-49ED-AC77-C9F515C9F0E9}.Release|x86.Build.0 = Release|Win32
54 | EndGlobalSection
55 | GlobalSection(SolutionProperties) = preSolution
56 | HideSolutionNode = FALSE
57 | EndGlobalSection
58 | EndGlobal
59 |
--------------------------------------------------------------------------------
/HackRF_Transmitter/write_wav.h:
--------------------------------------------------------------------------------
1 | /*
2 | * PortAudio Portable Real-Time Audio Library
3 | * Latest Version at: http://www.portaudio.com
4 | *
5 | * Copyright (c) 1999-2010 Phil Burk and Ross Bencina
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining
8 | * a copy of this software and associated documentation files
9 | * (the "Software"), to deal in the Software without restriction,
10 | * including without limitation the rights to use, copy, modify, merge,
11 | * publish, distribute, sublicense, and/or sell copies of the Software,
12 | * and to permit persons to whom the Software is furnished to do so,
13 | * subject to the following conditions:
14 | *
15 | * The above copyright notice and this permission notice shall be
16 | * included in all copies or substantial portions of the Software.
17 | *
18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
22 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
23 | * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 | */
26 |
27 | /*
28 | * The text above constitutes the entire PortAudio license; however,
29 | * the PortAudio community also makes the following non-binding requests:
30 | *
31 | * Any person wishing to distribute modifications to the Software is
32 | * requested to send the modifications to the original developer so that
33 | * they can be incorporated into the canonical version. It is also
34 | * requested that these non-binding requests be included along with the
35 | * license above.
36 | */
37 | #ifndef _WAV_WRITER_H
38 | #define _WAV_WRITER_H
39 |
40 | /*
41 | * WAV file writer.
42 | *
43 | * Author: Phil Burk
44 | */
45 |
46 | #ifdef __cplusplus
47 | extern "C" {
48 | #endif
49 |
50 | /* Define WAV Chunk and FORM types as 4 byte integers. */
51 | #define RIFF_ID (('R'<<24) | ('I'<<16) | ('F'<<8) | 'F')
52 | #define WAVE_ID (('W'<<24) | ('A'<<16) | ('V'<<8) | 'E')
53 | #define FMT_ID (('f'<<24) | ('m'<<16) | ('t'<<8) | ' ')
54 | #define DATA_ID (('d'<<24) | ('a'<<16) | ('t'<<8) | 'a')
55 | #define FACT_ID (('f'<<24) | ('a'<<16) | ('c'<<8) | 't')
56 |
57 | /* Errors returned by Audio_ParseSampleImage_WAV */
58 | #define WAV_ERR_CHUNK_SIZE (-1) /* Chunk size is illegal or past file size. */
59 | #define WAV_ERR_FILE_TYPE (-2) /* Not a WAV file. */
60 | #define WAV_ERR_ILLEGAL_VALUE (-3) /* Illegal or unsupported value. Eg. 927 bits/sample */
61 | #define WAV_ERR_FORMAT_TYPE (-4) /* Unsupported format, eg. compressed. */
62 | #define WAV_ERR_TRUNCATED (-5) /* End of file missing. */
63 |
64 | /* WAV PCM data format ID */
65 | #define WAVE_FORMAT_PCM (0x0001)
66 | #define WAVE_FORMAT_IEEE_FLOAT (0x0003)
67 | #define WAVE_FORMAT_IMA_ADPCM (0x0011)
68 |
69 |
70 | typedef struct WAV_Writer_s
71 | {
72 | FILE *fid;
73 | /* Offset in file for data size. */
74 | int dataSizeOffset;
75 | int dataSize;
76 | } WAV_Writer;
77 |
78 | /*********************************************************************************
79 | * Open named file and write WAV header to the file.
80 | * The header includes the DATA chunk type and size.
81 | * Returns number of bytes written to file or negative error code.
82 | */
83 | long Audio_WAV_OpenWriter( WAV_Writer *writer, const char *fileName, int frameRate, int samplesPerFrame );
84 |
85 | /*********************************************************************************
86 | * Write to the data chunk portion of a WAV file.
87 | * Returns bytes written or negative error code.
88 | */
89 | long Audio_WAV_WriteShorts( WAV_Writer *writer,
90 | short *samples,
91 | int numSamples
92 | );
93 |
94 | /*********************************************************************************
95 | * Close WAV file.
96 | * Update chunk sizes so it can be read by audio applications.
97 | */
98 | long Audio_WAV_CloseWriter( WAV_Writer *writer );
99 |
100 | #ifdef __cplusplus
101 | };
102 | #endif
103 |
104 | #endif /* _WAV_WRITER_H */
105 |
--------------------------------------------------------------------------------
/HackRF_Transmitter/FMModulator.cpp:
--------------------------------------------------------------------------------
1 | #include "FMModulator.h"
2 |
3 |
4 | #define BUF_NUM 256
5 | #define BYTES_PER_SAMPLE 2
6 | #define M_PI 3.14159265358979323846
7 |
8 |
9 | FMModulator::FMModulator(float _gain, uint32_t _mode, uint32_t _sample)
10 | :gain(_gain / (float)100.0), mode(_mode), inited(false), hackrf_sample(_sample)
11 | {
12 | audio_buf = NULL;
13 | new_audio_buf = NULL;
14 | IQ_buf = NULL;
15 | memset(last_in_samples, 0, sizeof(last_in_samples));
16 |
17 | count = tail = head = 0;
18 |
19 | _buf_ptr = (int8_t **)malloc(BUF_NUM * sizeof(int8_t *));
20 | if (_buf_ptr) {
21 | for (unsigned int i = 0; i < BUF_NUM; ++i) {
22 | _buf_ptr[i] = (int8_t *)malloc(BUF_LEN*sizeof(int8_t));
23 | }
24 | }
25 | }
26 |
27 |
28 | FMModulator::~FMModulator()
29 | {
30 | if (_buf_ptr) {
31 | for (unsigned int i = 0; i < BUF_NUM; ++i) {
32 | if (_buf_ptr[i])
33 | free(_buf_ptr[i]);
34 | }
35 | free(_buf_ptr);
36 | }
37 |
38 | delete IQ_buf;
39 | delete new_audio_buf;
40 | delete audio_buf;
41 | }
42 |
43 | void FMModulator::interpolation(float * in_buf, uint32_t in_samples, float * out_buf, uint32_t out_samples, float last_in_samples[4]) {
44 | uint32_t i; /* Input buffer index + 1. */
45 | uint32_t j = 0; /* Output buffer index. */
46 | float pos; /* Position relative to the input buffer
47 | * + 1.0. */
48 |
49 | /* We always "stay one sample behind", so what would be our first sample
50 | * should be the last one wrote by the previous call. */
51 | pos = (float)in_samples / (float)out_samples;
52 | while (pos < 1.0)
53 | {
54 | out_buf[j] = last_in_samples[3] + (in_buf[0] - last_in_samples[3]) * pos;
55 | j++;
56 | pos = (float)(j + 1)* (float)in_samples / (float)out_samples;
57 | }
58 |
59 | /* Interpolation cycle. */
60 | i = (uint32_t)pos;
61 | while (j < (out_samples - 1))
62 | {
63 |
64 | out_buf[j] = in_buf[i - 1] + (in_buf[i] - in_buf[i - 1]) * (pos - (float)i);
65 | j++;
66 | pos = (float)(j + 1)* (float)in_samples / (float)out_samples;
67 | i = (uint32_t)pos;
68 | }
69 |
70 | /* The last sample is always the same in input and output buffers. */
71 | out_buf[j] = in_buf[in_samples - 1];
72 |
73 | /* Copy last samples to last_in_samples (reusing i and j). */
74 | for (i = in_samples - 4, j = 0; j < 4; i++, j++)
75 | last_in_samples[j] = in_buf[i];
76 | }
77 |
78 | void FMModulator::modulation(float * input, float * output, uint32_t mode) {
79 | if (mode == 0) {
80 | fm_deviation = 2.0 * M_PI * 75.0e3 / hackrf_sample; // 75 kHz max deviation WBFM
81 | }
82 | else if (mode == 1)
83 | {
84 | fm_deviation = 2.0 * M_PI * 5.0e3 / hackrf_sample; // 5 kHz max deviation NBFM
85 | }
86 |
87 | //AM mode
88 | if (mode == 2) {
89 | for (uint32_t i = 0; i < BUF_LEN; i++) {
90 | double audio_amp = input[i] * gain;
91 |
92 | if (fabs(audio_amp) > 1.0) {
93 | audio_amp = (audio_amp > 0.0) ? 1.0 : -1.0;
94 | }
95 |
96 | IQ_buf[i * BYTES_PER_SAMPLE] = (float)audio_amp;
97 | IQ_buf[i * BYTES_PER_SAMPLE + 1] = 0;
98 | }
99 | }
100 | //FM mode
101 | else {
102 |
103 | for (uint32_t i = 0; i < BUF_LEN; i++) {
104 |
105 | double audio_amp = input[i] * gain;
106 |
107 | if (fabs(audio_amp) > 1.0) {
108 | audio_amp = (audio_amp > 0.0) ? 1.0 : -1.0;
109 | }
110 | fm_phase += fm_deviation * audio_amp;
111 | while (fm_phase > (float)(M_PI))
112 | fm_phase -= (float)(2.0 * M_PI);
113 | while (fm_phase < (float)(-M_PI))
114 | fm_phase += (float)(2.0 * M_PI);
115 |
116 | output[i * BYTES_PER_SAMPLE] = (float)sin(fm_phase);
117 | output[i * BYTES_PER_SAMPLE + 1] = (float)cos(fm_phase);
118 | }
119 | }
120 | }
121 |
122 | void FMModulator::work(float *input_items, uint32_t len) {
123 |
124 | m_mutex.lock();
125 | int8_t * buf = (int8_t *)_buf_ptr[head];
126 | for (uint32_t i = 0; i < BUF_LEN; i++) {
127 | buf[i] = (int8_t)(input_items[i] * 127.0);
128 | }
129 | head = (head + 1) % BUF_NUM;
130 | count++;
131 | m_mutex.unlock();
132 |
133 | }
134 | int FMModulator::onData(int8_t* buffer, uint32_t length)
135 | {
136 | m_mutex.lock();
137 |
138 | if (count == 0) {
139 | memset(buffer, 0, length);
140 | }
141 | else {
142 | memcpy(buffer, _buf_ptr[tail], length);
143 | tail = (tail + 1) % BUF_NUM;
144 | count--;
145 | }
146 | m_mutex.unlock();
147 |
148 | return 0;
149 | }
150 |
151 | void FMModulator::Start(WavSource *source)
152 | {
153 | int nch = source->getChannels();
154 | m_sample_count = source->getSampleCount();
155 | //hackrf_sample = m_sample_rate*1.0 / m_sample_count*BUF_LEN;
156 |
157 | float * source_audio_buf = source->getData();
158 |
159 | if (!inited) {
160 | audio_buf = new float[m_sample_count]();
161 | new_audio_buf = new float[BUF_LEN]();
162 | IQ_buf = new float[BUF_LEN * BYTES_PER_SAMPLE]();
163 | inited = true;
164 | }
165 |
166 | if (nch == 1) {
167 | for (uint32_t i = 0; i < m_sample_count; i++) {
168 |
169 | audio_buf[i] = source_audio_buf[i];
170 | }
171 | }
172 | else if (nch == 2) {
173 | for (uint32_t i = 0; i < m_sample_count; i++) {
174 |
175 | audio_buf[i] = (source_audio_buf[i * 2] + source_audio_buf[i * 2 + 1]) / (float)2.0;
176 | }
177 | }
178 |
179 | interpolation(audio_buf, m_sample_count, new_audio_buf, BUF_LEN, last_in_samples);
180 |
181 | modulation(new_audio_buf, IQ_buf, mode);
182 |
183 | for (uint32_t i = 0; i < (BUF_LEN * BYTES_PER_SAMPLE); i += BUF_LEN) {
184 |
185 | work(IQ_buf + i, BUF_LEN);
186 | }
187 |
188 | //AM mode
189 | }
190 |
--------------------------------------------------------------------------------
/HackRF_Transmitter/HackRF_Transmitter.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 | Debug
14 | x64
15 |
16 |
17 | Release
18 | x64
19 |
20 |
21 |
22 | {BD76BC64-68F9-470F-A778-593BC958D301}
23 | HackRF_Transmitter
24 | 8.1
25 |
26 |
27 |
28 | Application
29 | true
30 | v120
31 | Unicode
32 |
33 |
34 | Application
35 | false
36 | v120
37 | true
38 | Unicode
39 |
40 |
41 | Application
42 | true
43 | v120
44 | MultiByte
45 |
46 |
47 | Application
48 | false
49 | v140
50 | true
51 | MultiByte
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 | Level3
75 | Disabled
76 | true
77 | _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
78 | MultiThreadedDebug
79 | F:\projects\HackRF_Transmitter;%(AdditionalIncludeDirectories)
80 |
81 |
82 | libhackrf.lib;Winmm.lib;%(AdditionalDependencies)
83 | F:\projects\HackRF_Transmitter\Debug;%(AdditionalLibraryDirectories)
84 | true
85 |
86 |
87 |
88 |
89 | Level3
90 | Disabled
91 | true
92 | _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
93 |
94 |
95 | libhackrf.lib;%(AdditionalDependencies)
96 |
97 |
98 |
99 |
100 | Level3
101 | MaxSpeed
102 | true
103 | true
104 | true
105 |
106 |
107 | true
108 | true
109 |
110 |
111 |
112 |
113 | Level3
114 | MaxSpeed
115 | true
116 | true
117 | true
118 |
119 |
120 | true
121 | true
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
--------------------------------------------------------------------------------
/HackRF_Transmitter/write_wav.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * PortAudio Portable Real-Time Audio Library
3 | * Latest Version at: http://www.portaudio.com
4 | *
5 | * Copyright (c) 1999-2010 Phil Burk and Ross Bencina
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining
8 | * a copy of this software and associated documentation files
9 | * (the "Software"), to deal in the Software without restriction,
10 | * including without limitation the rights to use, copy, modify, merge,
11 | * publish, distribute, sublicense, and/or sell copies of the Software,
12 | * and to permit persons to whom the Software is furnished to do so,
13 | * subject to the following conditions:
14 | *
15 | * The above copyright notice and this permission notice shall be
16 | * included in all copies or substantial portions of the Software.
17 | *
18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
22 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
23 | * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 | */
26 |
27 | /*
28 | * The text above constitutes the entire PortAudio license; however,
29 | * the PortAudio community also makes the following non-binding requests:
30 | *
31 | * Any person wishing to distribute modifications to the Software is
32 | * requested to send the modifications to the original developer so that
33 | * they can be incorporated into the canonical version. It is also
34 | * requested that these non-binding requests be included along with the
35 | * license above.
36 | */
37 |
38 | /**
39 | * Very simple WAV file writer for saving captured audio.
40 | */
41 | #include
42 | #include
43 | #include "write_wav.h"
44 |
45 |
46 | /* Write long word data to a little endian format byte array. */
47 | static void WriteLongLE( unsigned char **addrPtr, unsigned long data )
48 | {
49 | unsigned char *addr = *addrPtr;
50 | *addr++ = (unsigned char) data;
51 | *addr++ = (unsigned char) (data>>8);
52 | *addr++ = (unsigned char) (data>>16);
53 | *addr++ = (unsigned char) (data>>24);
54 | *addrPtr = addr;
55 | }
56 |
57 | /* Write short word data to a little endian format byte array. */
58 | static void WriteShortLE( unsigned char **addrPtr, unsigned short data )
59 | {
60 | unsigned char *addr = *addrPtr;
61 | *addr++ = (unsigned char) data;
62 | *addr++ = (unsigned char) (data>>8);
63 | *addrPtr = addr;
64 | }
65 |
66 | /* Write IFF ChunkType data to a byte array. */
67 | static void WriteChunkType( unsigned char **addrPtr, unsigned long cktyp )
68 | {
69 | unsigned char *addr = *addrPtr;
70 | *addr++ = (unsigned char) (cktyp>>24);
71 | *addr++ = (unsigned char) (cktyp>>16);
72 | *addr++ = (unsigned char) (cktyp>>8);
73 | *addr++ = (unsigned char) cktyp;
74 | *addrPtr = addr;
75 | }
76 |
77 | #define WAV_HEADER_SIZE (4 + 4 + 4 + /* RIFF+size+WAVE */ \
78 | 4 + 4 + 16 + /* fmt chunk */ \
79 | 4 + 4 ) /* data chunk */
80 |
81 |
82 | /*********************************************************************************
83 | * Open named file and write WAV header to the file.
84 | * The header includes the DATA chunk type and size.
85 | * Returns number of bytes written to file or negative error code.
86 | */
87 | long Audio_WAV_OpenWriter( WAV_Writer *writer, const char *fileName, int frameRate, int samplesPerFrame )
88 | {
89 | unsigned int bytesPerSecond;
90 | unsigned char header[ WAV_HEADER_SIZE ];
91 | unsigned char *addr = header;
92 | int numWritten;
93 |
94 | writer->dataSize = 0;
95 | writer->dataSizeOffset = 0;
96 |
97 | writer->fid = fopen( fileName, "wb" );
98 | if( writer->fid == NULL )
99 | {
100 | return -1;
101 | }
102 |
103 | /* Write RIFF header. */
104 | WriteChunkType( &addr, RIFF_ID );
105 |
106 | /* Write RIFF size as zero for now. Will patch later. */
107 | WriteLongLE( &addr, 0 );
108 |
109 | /* Write WAVE form ID. */
110 | WriteChunkType( &addr, WAVE_ID );
111 |
112 | /* Write format chunk based on AudioSample structure. */
113 | WriteChunkType( &addr, FMT_ID );
114 | WriteLongLE( &addr, 16 );
115 | WriteShortLE(&addr, WAVE_FORMAT_IEEE_FLOAT);
116 | bytesPerSecond = frameRate * samplesPerFrame * sizeof( short);
117 | WriteShortLE( &addr, (short) samplesPerFrame );
118 | WriteLongLE( &addr, frameRate );
119 | WriteLongLE( &addr, bytesPerSecond );
120 | WriteShortLE( &addr, (short) (samplesPerFrame * sizeof( short)) ); /* bytesPerBlock */
121 | WriteShortLE( &addr, (short) 32 ); /* bits per sample */
122 |
123 | /* Write ID and size for 'data' chunk. */
124 | WriteChunkType( &addr, DATA_ID );
125 | /* Save offset so we can patch it later. */
126 | writer->dataSizeOffset = (int) (addr - header);
127 | WriteLongLE( &addr, 0 );
128 |
129 | numWritten = fwrite( header, 1, sizeof(header), writer->fid );
130 | if( numWritten != sizeof(header) ) return -1;
131 |
132 | return (int) numWritten;
133 | }
134 |
135 | /*********************************************************************************
136 | * Write to the data chunk portion of a WAV file.
137 | * Returns bytes written or negative error code.
138 | */
139 | long Audio_WAV_WriteShorts( WAV_Writer *writer,
140 | short *samples,
141 | int numSamples
142 | )
143 | {
144 | unsigned char buffer[2];
145 | unsigned char *bufferPtr;
146 | int i;
147 | short *p = samples;
148 | int numWritten;
149 | int bytesWritten;
150 | if( numSamples <= 0 )
151 | {
152 | return -1;
153 | }
154 |
155 | for( i=0; ifid );
160 | if( numWritten != sizeof(buffer) ) return -1;
161 | }
162 | bytesWritten = numSamples * sizeof(short);
163 | writer->dataSize += bytesWritten;
164 | return (int) bytesWritten;
165 | }
166 |
167 | /*********************************************************************************
168 | * Close WAV file.
169 | * Update chunk sizes so it can be read by audio applications.
170 | */
171 | long Audio_WAV_CloseWriter( WAV_Writer *writer )
172 | {
173 | unsigned char buffer[4];
174 | unsigned char *bufferPtr;
175 | int numWritten;
176 | int riffSize;
177 |
178 | /* Go back to beginning of file and update DATA size */
179 | int result = fseek( writer->fid, writer->dataSizeOffset, SEEK_SET );
180 | if( result < 0 ) return result;
181 |
182 | bufferPtr = buffer;
183 | WriteLongLE( &bufferPtr, writer->dataSize );
184 | numWritten = fwrite( buffer, 1, sizeof( buffer), writer->fid );
185 | if( numWritten != sizeof(buffer) ) return -1;
186 |
187 | /* Update RIFF size */
188 | result = fseek( writer->fid, 4, SEEK_SET );
189 | if( result < 0 ) return result;
190 |
191 | riffSize = writer->dataSize + (WAV_HEADER_SIZE - 8);
192 | bufferPtr = buffer;
193 | WriteLongLE( &bufferPtr, riffSize );
194 | numWritten = fwrite( buffer, 1, sizeof( buffer), writer->fid );
195 | if( numWritten != sizeof(buffer) ) return -1;
196 |
197 | fclose( writer->fid );
198 | writer->fid = NULL;
199 | return writer->dataSize;
200 | }
201 |
202 | /*********************************************************************************
203 | * Simple test that write a sawtooth waveform to a file.
204 | */
205 | #if 0
206 | int main( void )
207 | {
208 | int i;
209 | WAV_Writer writer;
210 | int result;
211 | #define NUM_SAMPLES (200)
212 | short data[NUM_SAMPLES];
213 | short saw = 0;
214 |
215 | for( i=0; i
3 | Copyright (c) 2013, Benjamin Vernoux
4 | Copyright (c) 2013, Michael Ossmann
5 |
6 | All rights reserved.
7 |
8 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
9 |
10 | Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
11 | Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
12 | documentation and/or other materials provided with the distribution.
13 | Neither the name of Great Scott Gadgets nor the names of its contributors may be used to endorse or promote products derived from this software
14 | without specific prior written permission.
15 |
16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
17 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
21 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22 | */
23 |
24 | #ifndef __HACKRF_H__
25 | #define __HACKRF_H__
26 |
27 | #include
28 |
29 | #ifdef _WIN32
30 | #define ADD_EXPORTS
31 |
32 | /* You should define ADD_EXPORTS *only* when building the DLL. */
33 | #ifdef ADD_EXPORTS
34 | #define ADDAPI __declspec(dllexport)
35 | #else
36 | #define ADDAPI __declspec(dllimport)
37 | #endif
38 |
39 | /* Define calling convention in one place, for convenience. */
40 | #define ADDCALL __cdecl
41 |
42 | #else /* _WIN32 not defined. */
43 |
44 | /* Define with no value on non-Windows OSes. */
45 | #define ADDAPI
46 | #define ADDCALL
47 |
48 | #endif
49 |
50 | enum hackrf_error {
51 | HACKRF_SUCCESS = 0,
52 | HACKRF_TRUE = 1,
53 | HACKRF_ERROR_INVALID_PARAM = -2,
54 | HACKRF_ERROR_NOT_FOUND = -5,
55 | HACKRF_ERROR_BUSY = -6,
56 | HACKRF_ERROR_NO_MEM = -11,
57 | HACKRF_ERROR_LIBUSB = -1000,
58 | HACKRF_ERROR_THREAD = -1001,
59 | HACKRF_ERROR_STREAMING_THREAD_ERR = -1002,
60 | HACKRF_ERROR_STREAMING_STOPPED = -1003,
61 | HACKRF_ERROR_STREAMING_EXIT_CALLED = -1004,
62 | HACKRF_ERROR_OTHER = -9999,
63 | };
64 |
65 | enum hackrf_board_id {
66 | BOARD_ID_JELLYBEAN = 0,
67 | BOARD_ID_JAWBREAKER = 1,
68 | BOARD_ID_HACKRF_ONE = 2,
69 | BOARD_ID_INVALID = 0xFF,
70 | };
71 |
72 | enum hackrf_usb_board_id {
73 | USB_BOARD_ID_JAWBREAKER = 0x604B,
74 | USB_BOARD_ID_HACKRF_ONE = 0x6089,
75 | USB_BOARD_ID_RAD1O = 0xCC15,
76 | USB_BOARD_ID_INVALID = 0xFFFF,
77 | };
78 |
79 | enum rf_path_filter {
80 | RF_PATH_FILTER_BYPASS = 0,
81 | RF_PATH_FILTER_LOW_PASS = 1,
82 | RF_PATH_FILTER_HIGH_PASS = 2,
83 | };
84 |
85 | typedef enum {
86 | TRANSCEIVER_MODE_OFF = 0,
87 | TRANSCEIVER_MODE_RX = 1,
88 | TRANSCEIVER_MODE_TX = 2,
89 | TRANSCEIVER_MODE_SS = 3,
90 | TRANSCEIVER_MODE_CPLD_UPDATE = 4
91 | } transceiver_mode_t;
92 |
93 | typedef struct hackrf_device hackrf_device;
94 |
95 | typedef struct {
96 | hackrf_device* device;
97 | uint8_t* buffer;
98 | int buffer_length;
99 | int valid_length;
100 | void* rx_ctx;
101 | void* tx_ctx;
102 | } hackrf_transfer;
103 |
104 | typedef struct {
105 | uint32_t part_id[2];
106 | uint32_t serial_no[4];
107 | } read_partid_serialno_t;
108 |
109 |
110 | struct hackrf_device_list {
111 | char **serial_numbers;
112 | enum hackrf_usb_board_id *usb_board_ids;
113 | int *usb_device_index;
114 | int devicecount;
115 |
116 | void **usb_devices;
117 | int usb_devicecount;
118 | };
119 | typedef struct hackrf_device_list hackrf_device_list_t;
120 |
121 | typedef int (*hackrf_sample_block_cb_fn)(hackrf_transfer* transfer);
122 |
123 | #ifdef __cplusplus
124 | extern "C"
125 | {
126 | #endif
127 |
128 | extern ADDAPI int ADDCALL hackrf_init();
129 | extern ADDAPI int ADDCALL hackrf_exit();
130 |
131 | extern ADDAPI hackrf_device_list_t* ADDCALL hackrf_device_list();
132 | extern ADDAPI int ADDCALL hackrf_device_list_open(hackrf_device_list_t *list, int idx, hackrf_device** device);
133 | extern ADDAPI void ADDCALL hackrf_device_list_free(hackrf_device_list_t *list);
134 |
135 | extern ADDAPI int ADDCALL hackrf_open(hackrf_device** device);
136 | extern ADDAPI int ADDCALL hackrf_open_by_serial(const char* const desired_serial_number, hackrf_device** device);
137 | extern ADDAPI int ADDCALL hackrf_close(hackrf_device* device);
138 |
139 | extern ADDAPI int ADDCALL hackrf_start_rx(hackrf_device* device, hackrf_sample_block_cb_fn callback, void* rx_ctx);
140 | extern ADDAPI int ADDCALL hackrf_stop_rx(hackrf_device* device);
141 |
142 | extern ADDAPI int ADDCALL hackrf_start_tx(hackrf_device* device, hackrf_sample_block_cb_fn callback, void* tx_ctx);
143 | extern ADDAPI int ADDCALL hackrf_stop_tx(hackrf_device* device);
144 |
145 | /* return HACKRF_TRUE if success */
146 | extern ADDAPI int ADDCALL hackrf_is_streaming(hackrf_device* device);
147 |
148 | extern ADDAPI int ADDCALL hackrf_max2837_read(hackrf_device* device, uint8_t register_number, uint16_t* value);
149 | extern ADDAPI int ADDCALL hackrf_max2837_write(hackrf_device* device, uint8_t register_number, uint16_t value);
150 |
151 | extern ADDAPI int ADDCALL hackrf_si5351c_read(hackrf_device* device, uint16_t register_number, uint16_t* value);
152 | extern ADDAPI int ADDCALL hackrf_si5351c_write(hackrf_device* device, uint16_t register_number, uint16_t value);
153 |
154 | extern ADDAPI int ADDCALL hackrf_set_baseband_filter_bandwidth(hackrf_device* device, const uint32_t bandwidth_hz);
155 |
156 | extern ADDAPI int ADDCALL hackrf_rffc5071_read(hackrf_device* device, uint8_t register_number, uint16_t* value);
157 | extern ADDAPI int ADDCALL hackrf_rffc5071_write(hackrf_device* device, uint8_t register_number, uint16_t value);
158 |
159 | extern ADDAPI int ADDCALL hackrf_spiflash_erase(hackrf_device* device);
160 | extern ADDAPI int ADDCALL hackrf_spiflash_write(hackrf_device* device, const uint32_t address, const uint16_t length, unsigned char* const data);
161 | extern ADDAPI int ADDCALL hackrf_spiflash_read(hackrf_device* device, const uint32_t address, const uint16_t length, unsigned char* data);
162 |
163 | /* device will need to be reset after hackrf_cpld_write */
164 | extern ADDAPI int ADDCALL hackrf_cpld_write(hackrf_device* device,
165 | unsigned char* const data, const unsigned int total_length);
166 |
167 | extern ADDAPI int ADDCALL hackrf_board_id_read(hackrf_device* device, uint8_t* value);
168 | extern ADDAPI int ADDCALL hackrf_version_string_read(hackrf_device* device, char* version, uint8_t length);
169 |
170 | extern ADDAPI int ADDCALL hackrf_set_freq(hackrf_device* device, const uint64_t freq_hz);
171 | extern ADDAPI int ADDCALL hackrf_set_freq_explicit(hackrf_device* device,
172 | const uint64_t if_freq_hz, const uint64_t lo_freq_hz,
173 | const enum rf_path_filter path);
174 |
175 | /* currently 8-20Mhz - either as a fraction, i.e. freq 20000000hz divider 2 -> 10Mhz or as plain old 10000000hz (double)
176 | preferred rates are 8, 10, 12.5, 16, 20Mhz due to less jitter */
177 | extern ADDAPI int ADDCALL hackrf_set_sample_rate_manual(hackrf_device* device, const uint32_t freq_hz, const uint32_t divider);
178 | extern ADDAPI int ADDCALL hackrf_set_sample_rate(hackrf_device* device, const double freq_hz);
179 |
180 | /* external amp, bool on/off */
181 | extern ADDAPI int ADDCALL hackrf_set_amp_enable(hackrf_device* device, const uint8_t value);
182 |
183 | extern ADDAPI int ADDCALL hackrf_board_partid_serialno_read(hackrf_device* device, read_partid_serialno_t* read_partid_serialno);
184 |
185 | /* range 0-40 step 8d, IF gain in osmosdr */
186 | extern ADDAPI int ADDCALL hackrf_set_lna_gain(hackrf_device* device, uint32_t value);
187 |
188 | /* range 0-62 step 2db, BB gain in osmosdr */
189 | extern ADDAPI int ADDCALL hackrf_set_vga_gain(hackrf_device* device, uint32_t value);
190 |
191 | /* range 0-47 step 1db */
192 | extern ADDAPI int ADDCALL hackrf_set_txvga_gain(hackrf_device* device, uint32_t value);
193 |
194 | /* antenna port power control */
195 | extern ADDAPI int ADDCALL hackrf_set_antenna_enable(hackrf_device* device, const uint8_t value);
196 |
197 | extern ADDAPI const char* ADDCALL hackrf_error_name(enum hackrf_error errcode);
198 | extern ADDAPI const char* ADDCALL hackrf_board_id_name(enum hackrf_board_id board_id);
199 | extern ADDAPI const char* ADDCALL hackrf_usb_board_id_name(enum hackrf_usb_board_id usb_board_id);
200 | extern ADDAPI const char* ADDCALL hackrf_filter_path_name(const enum rf_path_filter path);
201 |
202 | /* Compute nearest freq for bw filter (manual filter) */
203 | extern ADDAPI uint32_t ADDCALL hackrf_compute_baseband_filter_bw_round_down_lt(const uint32_t bandwidth_hz);
204 | /* Compute best default value depending on sample rate (auto filter) */
205 | extern ADDAPI uint32_t ADDCALL hackrf_compute_baseband_filter_bw(const uint32_t bandwidth_hz);
206 |
207 | #ifdef __cplusplus
208 | } // __cplusplus defined.
209 | #endif
210 |
211 | #endif /*__HACKRF_H__*/
212 |
--------------------------------------------------------------------------------
/HackRF_Transmitter/input.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * FAAC - Freeware Advanced Audio Coder
3 | * Copyright (C) 2002 Krzysztof Nikiel
4 | *
5 | * This library is free software; you can redistribute it and/or
6 | * modify it under the terms of the GNU Lesser General Public
7 | * License as published by the Free Software Foundation; either
8 | * version 2.1 of the License, or (at your option) any later version.
9 | *
10 | * This library is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | * Lesser General Public License for more details.
14 |
15 | * You should have received a copy of the GNU Lesser General Public
16 | * License along with this library; if not, write to the Free Software
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 | *
19 | * $Id: input.c,v 1.16 2009/01/25 18:50:32 menno Exp $
20 | */
21 | #ifdef HAVE_CONFIG_H
22 | #include "config.h"
23 | #endif
24 |
25 | #include
26 | #include
27 | #include
28 |
29 | #ifdef _WIN32
30 | #include
31 | #include
32 | #endif
33 |
34 | #include "input.h"
35 |
36 | #define SWAP32(x) (((x & 0xff) << 24) | ((x & 0xff00) << 8) \
37 | | ((x & 0xff0000) >> 8) | ((x & 0xff000000) >> 24))
38 | #define SWAP16(x) (((x & 0xff) << 8) | ((x & 0xff00) >> 8))
39 |
40 | #ifdef WORDS_BIGENDIAN
41 | # define UINT32(x) SWAP32(x)
42 | # define UINT16(x) SWAP16(x)
43 | #else
44 | # define UINT32(x) (x)
45 | # define UINT16(x) (x)
46 | #endif
47 |
48 | typedef struct
49 | {
50 | u_int32_t label; /* 'RIFF' */
51 | u_int32_t length; /* Length of rest of file */
52 | u_int32_t chunk_type; /* 'WAVE' */
53 | }
54 | riff_t;
55 |
56 | typedef struct
57 | {
58 | u_int32_t label;
59 | u_int32_t len;
60 | }
61 | riffsub_t;
62 |
63 | #ifdef _MSC_VER
64 | #pragma pack(push, 1)
65 | #endif
66 |
67 | #define WAVE_FORMAT_PCM 1
68 | #define WAVE_FORMAT_FLOAT 3
69 | #define WAVE_FORMAT_EXTENSIBLE 0xfffe
70 | struct WAVEFORMATEX
71 | {
72 | u_int16_t wFormatTag;
73 | u_int16_t nChannels;
74 | u_int32_t nSamplesPerSec;
75 | u_int32_t nAvgBytesPerSec;
76 | u_int16_t nBlockAlign;
77 | u_int16_t wBitsPerSample;
78 | u_int16_t cbSize;
79 | }
80 | #ifdef __GNUC
81 | __attribute__((packed))
82 | #endif
83 | ;
84 |
85 | struct WAVEFORMATEXTENSIBLE
86 | {
87 | struct WAVEFORMATEX Format;
88 | union {
89 | u_int16_t wValidBitsPerSample; // bits of precision
90 | u_int16_t wSamplesPerBlock; // valid if wBitsPerSample==0
91 | u_int16_t wReserved; // If neither applies, set to zero.
92 | } Samples;
93 | u_int32_t dwChannelMask; // which channels are present in stream
94 | unsigned char SubFormat[16]; // guid
95 | }
96 | #ifdef __GNUC
97 | __attribute__((packed))
98 | #endif
99 | ;
100 |
101 | #ifdef _MSC_VER
102 | #pragma pack(pop)
103 | #endif
104 |
105 | static unsigned char waveformat_pcm_guid[16] =
106 | {
107 | WAVE_FORMAT_PCM,0,0,0,
108 | 0x00, 0x00,
109 | 0x10, 0x00,
110 | 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71
111 | };
112 |
113 | static void unsuperr(const char *name)
114 | {
115 | fprintf(stderr, "%s: file format not supported\n", name);
116 | }
117 |
118 | pcmfile_t *wav_open_read(const char *name, int rawinput)
119 | {
120 | int i;
121 | int skip;
122 | FILE *wave_f;
123 | riff_t riff;
124 | riffsub_t riffsub;
125 | struct WAVEFORMATEXTENSIBLE wave;
126 | char *riffl = "RIFF";
127 | char *wavel = "WAVE";
128 | char *bextl = "BEXT";
129 | char *fmtl = "fmt ";
130 | char *datal = "data";
131 | int fmtsize;
132 | pcmfile_t *sndf;
133 | int dostdin = 0;
134 |
135 | if (!strcmp(name, "-"))
136 | {
137 | #ifdef _WIN32
138 | _setmode(_fileno(stdin), O_BINARY);
139 | #endif
140 | wave_f = stdin;
141 | dostdin = 1;
142 | }
143 | else if (!(wave_f = fopen(name, "rb")))
144 | {
145 | perror(name);
146 | return NULL;
147 | }
148 |
149 | if (!rawinput) // header input
150 | {
151 | if (fread(&riff, 1, sizeof(riff), wave_f) != sizeof(riff))
152 | return NULL;
153 | if (memcmp(&(riff.label), riffl, 4))
154 | return NULL;
155 | if (memcmp(&(riff.chunk_type), wavel, 4))
156 | return NULL;
157 |
158 | // handle broadcast extensions. added by pro-tools,otherwise it must be fmt chunk.
159 | if (fread(&riffsub, 1, sizeof(riffsub), wave_f) != sizeof(riffsub))
160 | return NULL;
161 | riffsub.len = UINT32(riffsub.len);
162 |
163 | if (!memcmp(&(riffsub.label), bextl, 4))
164 | {
165 | fseek(wave_f, riffsub.len, SEEK_CUR);
166 |
167 | if (fread(&riffsub, 1, sizeof(riffsub), wave_f) != sizeof(riffsub))
168 | return NULL;
169 | riffsub.len = UINT32(riffsub.len);
170 | }
171 |
172 | if (memcmp(&(riffsub.label), fmtl, 4))
173 | return NULL;
174 | memset(&wave, 0, sizeof(wave));
175 |
176 | fmtsize = (riffsub.len < sizeof(wave)) ? riffsub.len : sizeof(wave);
177 | if (fread(&wave, 1, fmtsize, wave_f) != fmtsize)
178 | return NULL;
179 |
180 | for (skip = riffsub.len - fmtsize; skip > 0; skip--)
181 | fgetc(wave_f);
182 |
183 | for (i = 0;; i++)
184 | {
185 | if (fread(&riffsub, 1, sizeof(riffsub), wave_f) != sizeof(riffsub))
186 | return NULL;
187 | riffsub.len = UINT32(riffsub.len);
188 | if (!memcmp(&(riffsub.label), datal, 4))
189 | break;
190 | if (i > 10)
191 | return NULL;
192 |
193 | for (skip = riffsub.len; skip > 0; skip--)
194 | fgetc(wave_f);
195 | }
196 | if (UINT16(wave.Format.wFormatTag) != WAVE_FORMAT_PCM && UINT16(wave.Format.wFormatTag) != WAVE_FORMAT_FLOAT)
197 | {
198 | if (UINT16(wave.Format.wFormatTag) == WAVE_FORMAT_EXTENSIBLE)
199 | {
200 | if (UINT16(wave.Format.cbSize) < 22) // struct too small
201 | return NULL;
202 | if (memcmp(wave.SubFormat, waveformat_pcm_guid, 16))
203 | {
204 | waveformat_pcm_guid[0] = WAVE_FORMAT_FLOAT;
205 | if (memcmp(wave.SubFormat, waveformat_pcm_guid, 16))
206 | {
207 | unsuperr(name);
208 | return NULL;
209 | }
210 | }
211 | }
212 | else
213 | {
214 | unsuperr(name);
215 | return NULL;
216 | }
217 | }
218 | }
219 |
220 | sndf = (pcmfile_t*)malloc(sizeof(*sndf));
221 | memset(sndf, 0, sizeof(*sndf));
222 | sndf->f = wave_f;
223 |
224 | if (UINT16(wave.Format.wFormatTag) == WAVE_FORMAT_FLOAT) {
225 | sndf->isfloat = 1;
226 | } else {
227 | sndf->isfloat = (wave.SubFormat[0] == WAVE_FORMAT_FLOAT);
228 | }
229 | if (rawinput)
230 | {
231 | sndf->bigendian = 1;
232 | if (dostdin)
233 | sndf->samples = 0;
234 | else
235 | {
236 | fseek(sndf->f, 0 , SEEK_END);
237 | sndf->samples = ftell(sndf->f);
238 | rewind(sndf->f);
239 | }
240 | }
241 | else
242 | {
243 | sndf->bigendian = 0;
244 | sndf->channels = UINT16(wave.Format.nChannels);
245 | sndf->samplebytes = UINT16(wave.Format.wBitsPerSample) / 8;
246 | sndf->samplerate = UINT32(wave.Format.nSamplesPerSec);
247 | sndf->samples = riffsub.len / (sndf->samplebytes * sndf->channels);
248 | }
249 | return sndf;
250 | }
251 |
252 |
253 | static void chan_remap(int32_t *buf, int channels, int blocks, int *map)
254 | {
255 | int i;
256 | int32_t *tmp = (int32_t*)malloc(channels * sizeof(int32_t));
257 |
258 | for (i = 0; i < blocks; i++)
259 | {
260 | int chn;
261 |
262 | memcpy(tmp, buf + i * channels, sizeof(int32_t) * channels);
263 |
264 | for (chn = 0; chn < channels; chn++)
265 | buf[i * channels + chn] = tmp[map[chn]];
266 | }
267 | }
268 |
269 | size_t wav_read_float32(pcmfile_t *sndf, float *buf, size_t num, int *map)
270 | {
271 | size_t i = 0;
272 | unsigned char bufi[8];
273 |
274 | if ((sndf->samplebytes > 8) || (sndf->samplebytes < 1))
275 | return 0;
276 |
277 | while (isamplebytes, 1, sndf->f) != 1)
279 | break;
280 |
281 | if (sndf->isfloat)
282 | {
283 | switch (sndf->samplebytes) {
284 | case 4:
285 | buf[i] = (*(float *)&bufi) * (float)32768;
286 | break;
287 |
288 | case 8:
289 | buf[i] = (float)((*(double *)&bufi) * (float)32768);
290 | break;
291 |
292 | default:
293 | return 0;
294 | }
295 | }
296 | else
297 | {
298 | // convert to 32 bit float
299 | // fix endianness
300 | switch (sndf->samplebytes) {
301 | case 1:
302 | /* this is endian clean */
303 | buf[i] = ((float)bufi[0] - 128) * (float)256;
304 | break;
305 |
306 | case 2:
307 | #ifdef WORDS_BIGENDIAN
308 | if (!sndf->bigendian)
309 | #else
310 | if (sndf->bigendian)
311 | #endif
312 | {
313 | // swap bytes
314 | int16_t s = ((int16_t *)bufi)[0];
315 | s = SWAP16(s);
316 | buf[i] = (float)s / 65530;
317 | }
318 | else
319 | {
320 | // no swap
321 | int s = ((int16_t *)bufi)[0];
322 | buf[i] = (float)s / 65530;
323 | }
324 | break;
325 |
326 | case 3:
327 | if (!sndf->bigendian)
328 | {
329 | int s = bufi[0] | (bufi[1] << 8) | (bufi[2] << 16);
330 |
331 | // fix sign
332 | if (s & 0x800000)
333 | s |= 0xff000000;
334 |
335 | buf[i] = (float)s / 256;
336 | }
337 | else // big endian input
338 | {
339 | int s = (bufi[0] << 16) | (bufi[1] << 8) | bufi[2];
340 |
341 | // fix sign
342 | if (s & 0x800000)
343 | s |= 0xff000000;
344 |
345 | buf[i] = (float)s / 256;
346 | }
347 | break;
348 |
349 | case 4:
350 | #ifdef WORDS_BIGENDIAN
351 | if (!sndf->bigendian)
352 | #else
353 | if (sndf->bigendian)
354 | #endif
355 | {
356 | // swap bytes
357 | int s = *(int *)&bufi;
358 | buf[i] = (float)SWAP32(s) / 65536;
359 | }
360 | else
361 | {
362 | int s = *(int *)&bufi;
363 | buf[i] = (float)s / 65536;
364 | }
365 | break;
366 |
367 | default:
368 | return 0;
369 | }
370 | }
371 | i++;
372 | }
373 |
374 | if (map)
375 | chan_remap((int32_t *)buf, sndf->channels, i / sndf->channels, map);
376 |
377 | return i;
378 | }
379 |
380 | size_t wav_read_int24(pcmfile_t *sndf, int32_t *buf, size_t num, int *map)
381 | {
382 | int size;
383 | int i;
384 | unsigned char *bufi;
385 |
386 | if ((sndf->samplebytes > 4) || (sndf->samplebytes < 1))
387 | return 0;
388 |
389 | bufi = (unsigned char *) (char *)buf + sizeof(*buf) * num - sndf->samplebytes * (num - 1) - sizeof(*buf);
390 |
391 | size = fread(bufi, sndf->samplebytes, num, sndf->f);
392 |
393 | if(sizesamplebytes) {
401 | case 1:
402 | /* this is endian clean */
403 | for (i = 0; i < size; i++)
404 | buf[i] = (bufi[i] - 128) * 65536;
405 | break;
406 |
407 | case 2:
408 | #ifdef WORDS_BIGENDIAN
409 | if (!sndf->bigendian)
410 | #else
411 | if (sndf->bigendian)
412 | #endif
413 | {
414 | // swap bytes
415 | for (i = 0; i < size; i++)
416 | {
417 | int16_t s = ((int16_t *)bufi)[i];
418 |
419 | s = SWAP16(s);
420 |
421 | buf[i] = ((u_int32_t)s) << 8;
422 | }
423 | }
424 | else
425 | {
426 | // no swap
427 | for (i = 0; i < size; i++)
428 | {
429 | int s = ((int16_t *)bufi)[i];
430 |
431 | buf[i] = s << 8;
432 | }
433 | }
434 | break;
435 |
436 | case 3:
437 | if (!sndf->bigendian)
438 | {
439 | for (i = 0; i < size; i++)
440 | {
441 | int s = bufi[3 * i] | (bufi[3 * i + 1] << 8) | (bufi[3 * i + 2] << 16);
442 |
443 | // fix sign
444 | if (s & 0x800000)
445 | s |= 0xff000000;
446 |
447 | buf[i] = s;
448 | }
449 | }
450 | else // big endian input
451 | {
452 | for (i = 0; i < size; i++)
453 | {
454 | int s = (bufi[3 * i] << 16) | (bufi[3 * i + 1] << 8) | bufi[3 * i + 2];
455 |
456 | // fix sign
457 | if (s & 0x800000)
458 | s |= 0xff000000;
459 |
460 | buf[i] = s;
461 | }
462 | }
463 | break;
464 |
465 | case 4:
466 | #ifdef WORDS_BIGENDIAN
467 | if (!sndf->bigendian)
468 | #else
469 | if (sndf->bigendian)
470 | #endif
471 | {
472 | // swap bytes
473 | for (i = 0; i < size; i++)
474 | {
475 | int s = buf[i];
476 |
477 | buf[i] = SWAP32(s);
478 | }
479 | }
480 | break;
481 | }
482 |
483 | if (map)
484 | chan_remap(buf, sndf->channels, size / sndf->channels, map);
485 |
486 | return size;
487 | }
488 |
489 | size_t wav_read_int24_buf(pcmfile_t *sndf, int32_t *outbuf, size_t num, unsigned char *inputbuf)
490 | {
491 | size_t i=0,j=0;
492 | int16_t bufi;
493 |
494 | while(isamplebytes);
497 | j+=sndf->samplebytes;
498 | //int16_t s=((int16_t*)bufi)[0];
499 | outbuf[i]= bufi << 8;
500 | i++;
501 | }
502 | return j;
503 | }
504 |
505 | int wav_close(pcmfile_t *sndf)
506 | {
507 | int i = fclose(sndf->f);
508 | free(sndf);
509 | return i;
510 | }
511 |
--------------------------------------------------------------------------------