• We’re currently investigating an issue related to the forum theme and styling that is impacting page layout and visual formatting. The problem has been identified, and we are actively working on a resolution. There is no impact to user data or functionality, this is strictly a front-end display issue. We’ll post an update once the fix has been deployed. Thanks for your patience while we get this sorted.

Flatbed scanner used to obtain .wav file from phonograph record

This is actually fairly old... unless he's done some new work on this. I remember reading about this awhile ago...still cool nonetheless.
 
Originally posted by: murphy55d
This is actually fairly old... unless he's done some new work on this. I remember reading about this awhile ago...still cool nonetheless.

Yeah, it was posted here before.........who cares, still very cool.
 

/*
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

In addition, as a special exception, <Borland Software Corporation >
gives permission to link the code of this program with
the Kylix library, and distribute linked combinations including
the two. You must obey the GNU General Public License in all
respects for all of the code used other than Kylix. If you modify
this file, you may extend this exception to your version of the
file, but you are not obligated to do so. If you do not wish to
do so, delete this exception statement from your version.
*/



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

#include <vcl.h>

#pragma hdrstop

#include "dneedle.h"
#pragma package(smart_init)
#pragma resource "*.dfm"

TfrmMain *frmMain;


__fastcall
TfrmMain::TfrmMain (TComponent * Owner):
TForm (Owner)
{

isPositionCenterMode = false;
isPositionNeedleMode = false;

haltPlayback = false;
}


void __fastcall
TfrmMain::btnCenterClick (TObject * Sender)
{

isPositionCenterMode = true;
img->Cursor = crCross;
status->SimpleText = "Point at record's center";
}


void __fastcall
TfrmMain::btnNeedleClick (TObject * Sender)
{

isPositionNeedleMode = true;
img->Cursor = crCross;
status->SimpleText = "Point at needle position";
}


void __fastcall
TfrmMain::btnLoadClick (TObject * Sender)
{

dlgOpen->InitialDir = (AnsiString) BMP_PATH;

if (dlgOpen->Execute ())
img->Picture->LoadFromFile (dlgOpen->FileName);
}


void __fastcall
TfrmMain::imgMouseUp (TObject * Sender, TMouseButton Button,
TShiftState Shift, int X, int Y)
{

if (isPositionCenterMode)
{
centerX = X;
centerY = Y;
}

if (isPositionNeedleMode)
{
needleX = X;
needleY = Y;
}

isPositionNeedleMode = isPositionCenterMode = false;
img->Cursor = crDefault;

status->SimpleText = "";
}


void __fastcall
TfrmMain::btnHaltPlaybackClick (TObject * Sender)
{

haltPlayback = true;

}

void __fastcall
TfrmMain::btnPlayClick (TObject * Sender)
{

long double newNeedleX, newNeedleY;

long double curLum;
long double ndx, ndy;
long double dx = needleX - centerX;
long double dy = needleY - centerY;

long double stickyFact = txtSticky->Text.ToDouble ();

long double omega = txtOmega->Text.ToDouble ();

areaWidth = txtArea->Text.ToInt ();

long i, time, numSamples = txtSamples->Text.ToInt ();

long double mass = txtMass->Text.ToDouble ();
long double damping = txtDamping->Text.ToDouble ();

long double avgRadius, radius, dr;
long double avgRadiusSpeed, avgRadiusAccel;

long double alpha, alpha0;

// Allocate the sample buffers

long double *dBuf =
(long double *) malloc (sizeof (long double) * numSamples);
word *wBuf = (word *) malloc (sizeof (word) * numSamples);

radius = sqrtl (powl (dx, 2) + powl (dy, 2));
alpha0 = acos (dx / radius);

avgRadius = radius;
avgRadiusSpeed = 0;

for (time = 0; time < numSamples && !haltPlayback; time++)
{

// Idle background operations

if (time % NUM_ITERATIONS_TO_IDLE == 0)
{

img->Canvas->Refresh ();
Application->ProcessMessages ();
}

alpha = alpha0 + (omega * time);

needleX = ((radius * cos (alpha)) + centerX);
needleY = ((radius * sin (alpha)) + centerY);

curLum = getDirection (&ndx, &ndy);

newNeedleX = needleX + (ndx * stickyFact);
newNeedleY = needleY + (ndy * stickyFact);

radius = sqrtl (powl (newNeedleX - centerX, 2) +
powl (newNeedleY - centerY, 2));

dr = avgRadius - radius;
curLum = (curLum - 45) / 18;

// dBuf[time] = dr;
// dBuf[time] = curLum;

dBuf[time] = ((40 * dr) + (60 * curLum)) / 100;

avgRadiusAccel = -(dr / mass);
avgRadiusSpeed = (avgRadiusSpeed * damping) + avgRadiusAccel;
avgRadius += avgRadiusSpeed;

radius = ((100 * radius) + (35 * avgRadius)) / 135;
}

// Reset halt flag

if (haltPlayback)
haltPlayback = false;

// Filter dBuf into wBuf

for (i = 2; i < (time - 2); i++)
dBuf =
(dBuf[i - 2] + dBuf[i - 1] + dBuf + dBuf[i + 1] + dBuf[i + 2]) / 5;

for (i = 2; i < (time - 2); i++)
wBuf = (word) ((long) ((dBuf * 47 * 256) + 0.5));

// Write wBuf

FILE *fp = fopen (RAW_PATH, "wb");
fwrite (wBuf, 1, sizeof (word) * time, fp);

// Done

fclose (fp);
free (dBuf);
free (wBuf);

status->SimpleText = "Done.";
}


float _fastcall
TfrmMain::getDirection (long double *dx, long double *dy)
{

TColor curTCol;

float avgCol;
long sumCount = 0;
long sumCol = 0;

long cntCol;
long curCol;

long cntx = 0;
long cnty = 0;

long cntrx = (long) (needleX + 0.5);
long cntry = (long) (needleY + 0.5);

long x, y;

long double r;

curTCol = img->Canvas->Pixels[cntrx][cntry];
cntCol = (curTCol & 0x000000FF);

(*dx) = 0;
(*dy) = 0;

for (y = -areaWidth; y < areaWidth; y++)
{
for (x = -areaWidth; x < areaWidth; x++)
{

curTCol = img->Canvas->Pixels[cntrx + x][cntry + y];
curCol = (curTCol & 0x000000FF);

sumCol += curCol;
sumCount++;

if (x != 0)
{
(*dx) += ((curCol - cntCol) / x);
cntx++;
}

if (y != 0)
{
(*dy) += ((curCol - cntCol) / y);
cnty++;
}
}
}

(*dx) /= (cntx * 255);
(*dy) /= (cnty * 255);

r = sqrtl (powl ((*dx), 2) + powl ((*dy), 2));

if (r > 0)
{

(*dx) /= r;
(*dy) /= r;
}

else
{

(*dx) = 0;
(*dy) = 0;
}

img->Canvas->Pixels[needleX][needleY] = (TColor) (0x00FF0000 &
img->Canvas->
Pixels[needleX][needleY]);

avgCol = (float) sumCol / sumCount;
return avgCol;
}
 
Back
Top